@gradientlabs/client 0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Gradient Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,170 @@
1
+ # Gradient Labs Node.js / TypeScript client
2
+
3
+ Official client for the [Gradient Labs API](https://api.gradient-labs.ai). Written
4
+ in TypeScript, ships full type declarations and both ESM and CommonJS builds, and
5
+ has **zero runtime dependencies** (it uses Node's built-in `fetch` and `crypto`).
6
+
7
+ Requires **Node.js 20** or newer.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install @gradientlabs/client
13
+ ```
14
+
15
+ ## Quick start
16
+
17
+ ```ts
18
+ import { GradientLabs } from "@gradientlabs/client";
19
+
20
+ const client = new GradientLabs({ apiKey: process.env.GRADIENT_LABS_API_KEY! });
21
+
22
+ const conversation = await client.conversations.start({
23
+ id: "ticket-12345",
24
+ customer_id: "customer-678",
25
+ channel: "web",
26
+ assignee_type: "AI Agent",
27
+ });
28
+
29
+ console.log(conversation.status);
30
+ ```
31
+
32
+ The client is organised into resource namespaces, e.g. `client.conversations`,
33
+ `client.tools`, `client.procedures`. There are two API key roles:
34
+
35
+ - **Integration** — conversation runtime endpoints (`conversations`,
36
+ `outboundConversations`, `backOfficeTasks`, `voice`).
37
+ - **Management** — configuration endpoints (`tools`, `articles`, `topics`,
38
+ `procedures`, `handOffTargets`, `resourceSources`, `resourceTypes`, `secrets`,
39
+ `notes`, `terminologySubstitutions`, `trafficGroups`, `ipAddresses`).
40
+
41
+ ## Configuration
42
+
43
+ ```ts
44
+ const client = new GradientLabs({
45
+ apiKey: "sk_live_...", // required
46
+ baseUrl: "https://api.gradient-labs.ai", // optional (this is the default)
47
+ webhookSigningKey: "whsec_...", // optional, required to verify webhooks
48
+ webhookLeewayMs: 5 * 60 * 1000, // optional, default 5 minutes
49
+ timeoutMs: 30_000, // optional per-request timeout
50
+ fetch: myFetch, // optional, inject a custom fetch (tests, proxies, instrumentation)
51
+ });
52
+ ```
53
+
54
+ Every method accepts an optional final argument carrying an `AbortSignal` for
55
+ cancellation:
56
+
57
+ ```ts
58
+ const controller = new AbortController();
59
+ const tools = await client.tools.list({ signal: controller.signal });
60
+ ```
61
+
62
+ ## Error handling
63
+
64
+ Non-2xx responses throw an `ApiError`; client misconfiguration throws a
65
+ `ConfigurationError`. Both extend `GradientLabsError`.
66
+
67
+ ```ts
68
+ import { ApiError, ErrorCode } from "@gradientlabs/client";
69
+
70
+ try {
71
+ await client.conversations.get("missing");
72
+ } catch (err) {
73
+ if (err instanceof ApiError) {
74
+ console.error(err.statusCode, err.code, err.message);
75
+ if (err.code === ErrorCode.NotFound) {
76
+ // handle 404
77
+ }
78
+ console.error("trace id:", err.traceId); // give this to support
79
+ }
80
+ }
81
+ ```
82
+
83
+ The client never retries failed requests — retry policy is left to you.
84
+
85
+ ## Pagination
86
+
87
+ List endpoints that paginate return a `Page<T>` with opaque `next`/`prev`
88
+ cursors. Use `listAll()` to iterate every page automatically:
89
+
90
+ ```ts
91
+ for await (const procedure of client.procedures.listAll()) {
92
+ console.log(procedure.name);
93
+ }
94
+
95
+ // or page manually:
96
+ const page = await client.procedures.list();
97
+ const next = await client.procedures.list({ cursor: page.pageInfo.next });
98
+ ```
99
+
100
+ ## Webhook verification
101
+
102
+ Construct the client with your `webhookSigningKey`, then verify and parse
103
+ incoming requests. Pass the **raw** request body — the signature is computed over
104
+ the exact bytes received.
105
+
106
+ ```ts
107
+ import { GradientLabs, InvalidWebhookSignatureError } from "@gradientlabs/client";
108
+
109
+ const client = new GradientLabs({
110
+ apiKey: process.env.GRADIENT_LABS_API_KEY!,
111
+ webhookSigningKey: process.env.GL_WEBHOOK_SIGNING_KEY!,
112
+ });
113
+
114
+ // Express example (use express.raw() so req.body is the raw payload):
115
+ app.post("/webhooks", express.raw({ type: "*/*" }), (req, res) => {
116
+ try {
117
+ const { event, token } = client.webhooks.parse({
118
+ body: req.body, // Buffer
119
+ headers: req.headers,
120
+ });
121
+
122
+ switch (event.type) {
123
+ case "agent.message":
124
+ console.log(event.data.body);
125
+ break;
126
+ case "conversation.hand_off":
127
+ console.log(event.data.reason_code);
128
+ break;
129
+ // ...other event types
130
+ }
131
+
132
+ res.sendStatus(200);
133
+ } catch (err) {
134
+ if (err instanceof InvalidWebhookSignatureError) {
135
+ res.sendStatus(401);
136
+ } else {
137
+ res.sendStatus(500);
138
+ }
139
+ }
140
+ });
141
+ ```
142
+
143
+ `event` is a discriminated union on `event.type`, so narrowing gives you a
144
+ fully-typed `event.data`. The optional `X-GradientLabs-Token` header is returned
145
+ as `token`.
146
+
147
+ Supported event types: `agent.message`, `conversation.hand_off`,
148
+ `conversation.finished`, `action.execute`, `resource.pull`,
149
+ `back-office-task.complete`, `back-office-task.hand-off`, `back-office-task.fail`.
150
+
151
+ ## Examples
152
+
153
+ See the [`examples/`](./examples) directory for runnable examples covering
154
+ conversations, tools, articles, procedures, resources, back-office tasks, and a
155
+ webhook server.
156
+
157
+ ## Development
158
+
159
+ ```bash
160
+ npm install
161
+ npm run build # dual ESM/CJS + type declarations
162
+ npm test # vitest (no network required)
163
+ npm run lint
164
+ npm run typecheck
165
+ npm run format
166
+ ```
167
+
168
+ ## License
169
+
170
+ [MIT](./LICENSE)