@journeyrewards/hive-sdk 1.0.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/dist/index.mjs ADDED
@@ -0,0 +1,344 @@
1
+ // src/errors.ts
2
+ var JourneyHiveError = class extends Error {
3
+ constructor(status, type, code, message) {
4
+ super(message);
5
+ this.name = "JourneyHiveError";
6
+ this.status = status;
7
+ this.type = type;
8
+ this.code = code;
9
+ }
10
+ };
11
+ var AuthenticationError = class extends JourneyHiveError {
12
+ constructor(code, message) {
13
+ super(401, "authentication_error", code, message);
14
+ this.name = "AuthenticationError";
15
+ }
16
+ };
17
+ var RateLimitError = class extends JourneyHiveError {
18
+ constructor(code, message) {
19
+ super(429, "rate_limit_error", code, message);
20
+ this.name = "RateLimitError";
21
+ }
22
+ };
23
+ var NotFoundError = class extends JourneyHiveError {
24
+ constructor(code, message) {
25
+ super(404, "not_found_error", code, message);
26
+ this.name = "NotFoundError";
27
+ }
28
+ };
29
+ var PermissionError = class extends JourneyHiveError {
30
+ constructor(code, message) {
31
+ super(403, "permission_error", code, message);
32
+ this.name = "PermissionError";
33
+ }
34
+ };
35
+ function parseErrorResponse(status, body) {
36
+ const error = body?.error;
37
+ const message = error?.message || "Unknown error";
38
+ const type = error?.type || "unknown_error";
39
+ const code = error?.code || "unknown";
40
+ switch (status) {
41
+ case 401:
42
+ return new AuthenticationError(code, message);
43
+ case 403:
44
+ return new PermissionError(code, message);
45
+ case 404:
46
+ return new NotFoundError(code, message);
47
+ case 429:
48
+ return new RateLimitError(code, message);
49
+ default:
50
+ return new JourneyHiveError(status, type, code, message);
51
+ }
52
+ }
53
+
54
+ // src/streaming.ts
55
+ async function* parseSSEStream(response) {
56
+ if (!response.body) {
57
+ throw new Error("Response body is null. Streaming is not supported.");
58
+ }
59
+ const reader = response.body.getReader();
60
+ const decoder = new TextDecoder();
61
+ let buffer = "";
62
+ try {
63
+ while (true) {
64
+ const { done, value } = await reader.read();
65
+ if (done) {
66
+ if (buffer.trim()) {
67
+ const event = parseSSEBlock(buffer);
68
+ if (event) yield event;
69
+ }
70
+ break;
71
+ }
72
+ buffer += decoder.decode(value, { stream: true });
73
+ const blocks = buffer.split("\n\n");
74
+ buffer = blocks.pop() || "";
75
+ for (const block of blocks) {
76
+ const trimmed = block.trim();
77
+ if (!trimmed) continue;
78
+ const event = parseSSEBlock(trimmed);
79
+ if (event) yield event;
80
+ }
81
+ }
82
+ } finally {
83
+ reader.releaseLock();
84
+ }
85
+ }
86
+ function parseSSEBlock(block) {
87
+ let eventType = "";
88
+ let dataStr = "";
89
+ const lines = block.split("\n");
90
+ for (const line of lines) {
91
+ if (line.startsWith("event: ")) {
92
+ eventType = line.slice(7).trim();
93
+ } else if (line.startsWith("data: ")) {
94
+ dataStr += line.slice(6);
95
+ } else if (line.startsWith("data:")) {
96
+ dataStr += line.slice(5);
97
+ }
98
+ }
99
+ if (!eventType || !dataStr) return null;
100
+ try {
101
+ const data = JSON.parse(dataStr);
102
+ return { type: eventType, ...data };
103
+ } catch {
104
+ return null;
105
+ }
106
+ }
107
+
108
+ // src/client.ts
109
+ var DEFAULT_BASE_URL = "https://journey-hive.replit.app";
110
+ var DEFAULT_TIMEOUT = 3e4;
111
+ var MAX_RETRIES = 3;
112
+ var RETRY_STATUS_CODES = [408, 429, 500, 502, 503, 504];
113
+ function sleep(ms) {
114
+ return new Promise((resolve) => setTimeout(resolve, ms));
115
+ }
116
+ var JourneyHiveClient = class {
117
+ constructor(config) {
118
+ if (!config.apiKey) {
119
+ throw new Error("apiKey is required");
120
+ }
121
+ this.apiKey = config.apiKey;
122
+ this.baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, "");
123
+ this.timeout = config.timeout || DEFAULT_TIMEOUT;
124
+ this.defaultAgentId = config.defaultAgentId;
125
+ this.debug = config.debug || false;
126
+ this.responses = new ResponsesAPI(this);
127
+ this.conversations = new ConversationsAPI(this);
128
+ this.agents = new AgentsAPI(this);
129
+ this.usage = new UsageAPI(this);
130
+ }
131
+ getDefaultAgentId() {
132
+ return this.defaultAgentId;
133
+ }
134
+ log(direction, method, path, body) {
135
+ if (!this.debug) return;
136
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
137
+ if (body) {
138
+ console.log(`[JourneyHive ${direction}] ${timestamp} ${method} ${path}`, JSON.stringify(body, null, 2));
139
+ } else {
140
+ console.log(`[JourneyHive ${direction}] ${timestamp} ${method} ${path}`);
141
+ }
142
+ }
143
+ async _fetch(path, options = {}) {
144
+ const { retries = MAX_RETRIES, idempotencyKey, ...fetchOptions } = options;
145
+ const url = `${this.baseUrl}${path}`;
146
+ const headers = {
147
+ Authorization: `Bearer ${this.apiKey}`,
148
+ "Content-Type": "application/json",
149
+ ...fetchOptions.headers || {}
150
+ };
151
+ if (idempotencyKey) {
152
+ headers["Idempotency-Key"] = idempotencyKey;
153
+ }
154
+ let parsedBody;
155
+ if (fetchOptions.body && typeof fetchOptions.body === "string") {
156
+ try {
157
+ parsedBody = JSON.parse(fetchOptions.body);
158
+ } catch {
159
+ parsedBody = fetchOptions.body;
160
+ }
161
+ }
162
+ this.log(">>>", fetchOptions.method || "GET", path, parsedBody);
163
+ let lastError = null;
164
+ for (let attempt = 0; attempt <= retries; attempt++) {
165
+ const controller = new AbortController();
166
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
167
+ try {
168
+ const response = await fetch(url, {
169
+ ...fetchOptions,
170
+ headers,
171
+ signal: controller.signal
172
+ });
173
+ clearTimeout(timeoutId);
174
+ if (!response.ok) {
175
+ if (attempt < retries && RETRY_STATUS_CODES.includes(response.status)) {
176
+ const delay = Math.min(1e3 * Math.pow(2, attempt), 1e4);
177
+ this.log("<<<", `${response.status}`, path, { retry: attempt + 1, delay });
178
+ await sleep(delay);
179
+ continue;
180
+ }
181
+ let body;
182
+ try {
183
+ body = await response.json();
184
+ } catch {
185
+ body = { error: { message: response.statusText } };
186
+ }
187
+ this.log("<<<", `${response.status}`, path, body);
188
+ throw parseErrorResponse(
189
+ response.status,
190
+ body
191
+ );
192
+ }
193
+ const requestId = response.headers.get("x-request-id");
194
+ if (requestId) {
195
+ this.log("<<<", "200", `${path} [req_id: ${requestId}]`);
196
+ } else {
197
+ this.log("<<<", "200", path);
198
+ }
199
+ return response;
200
+ } catch (err) {
201
+ clearTimeout(timeoutId);
202
+ if (err instanceof JourneyHiveError) {
203
+ throw err;
204
+ }
205
+ lastError = err;
206
+ if (attempt < retries) {
207
+ const delay = Math.min(1e3 * Math.pow(2, attempt), 1e4);
208
+ this.log("<<<", "ERR", path, { error: err.message, retry: attempt + 1 });
209
+ await sleep(delay);
210
+ continue;
211
+ }
212
+ }
213
+ }
214
+ throw lastError || new Error("Request failed after retries");
215
+ }
216
+ };
217
+ var ResponsesAPI = class {
218
+ constructor(client) {
219
+ this.client = client;
220
+ }
221
+ resolveAgentId(params) {
222
+ if (!params.agent_id && this.client.getDefaultAgentId()) {
223
+ return { ...params, agent_id: this.client.getDefaultAgentId() };
224
+ }
225
+ return params;
226
+ }
227
+ async create(params) {
228
+ const resolved = this.resolveAgentId(params);
229
+ const { idempotency_key, ...body } = resolved;
230
+ if (resolved.stream) {
231
+ const response2 = await this.client._fetch("/v1/responses", {
232
+ method: "POST",
233
+ body: JSON.stringify(body),
234
+ retries: 0,
235
+ idempotencyKey: idempotency_key
236
+ });
237
+ return parseSSEStream(response2);
238
+ }
239
+ const response = await this.client._fetch("/v1/responses", {
240
+ method: "POST",
241
+ body: JSON.stringify(body),
242
+ idempotencyKey: idempotency_key
243
+ });
244
+ return response.json();
245
+ }
246
+ async get(id) {
247
+ const response = await this.client._fetch(`/v1/responses/${encodeURIComponent(id)}`);
248
+ return response.json();
249
+ }
250
+ };
251
+ var ConversationsAPI = class {
252
+ constructor(client) {
253
+ this.client = client;
254
+ }
255
+ resolveAgentId(params) {
256
+ if (!params.agent_id && this.client.getDefaultAgentId()) {
257
+ return { ...params, agent_id: this.client.getDefaultAgentId() };
258
+ }
259
+ return params;
260
+ }
261
+ async create(params) {
262
+ const resolved = this.resolveAgentId(params);
263
+ const { idempotency_key, ...body } = resolved;
264
+ const response = await this.client._fetch("/v1/conversations", {
265
+ method: "POST",
266
+ body: JSON.stringify(body),
267
+ idempotencyKey: idempotency_key
268
+ });
269
+ return response.json();
270
+ }
271
+ async get(id) {
272
+ const response = await this.client._fetch(`/v1/conversations/${encodeURIComponent(id)}`);
273
+ return response.json();
274
+ }
275
+ async list(params) {
276
+ const searchParams = new URLSearchParams();
277
+ if (params?.agent_id) searchParams.set("agent_id", params.agent_id);
278
+ if (params?.status) searchParams.set("status", params.status);
279
+ if (params?.limit) searchParams.set("limit", String(params.limit));
280
+ if (params?.cursor) searchParams.set("cursor", params.cursor);
281
+ const query = searchParams.toString();
282
+ const path = `/v1/conversations${query ? `?${query}` : ""}`;
283
+ const response = await this.client._fetch(path);
284
+ return response.json();
285
+ }
286
+ async messages(id, params) {
287
+ const searchParams = new URLSearchParams();
288
+ if (params?.limit) searchParams.set("limit", String(params.limit));
289
+ if (params?.cursor) searchParams.set("cursor", params.cursor);
290
+ const query = searchParams.toString();
291
+ const response = await this.client._fetch(
292
+ `/v1/conversations/${encodeURIComponent(id)}/messages${query ? `?${query}` : ""}`
293
+ );
294
+ return response.json();
295
+ }
296
+ async close(id) {
297
+ await this.client._fetch(`/v1/conversations/${encodeURIComponent(id)}`, {
298
+ method: "DELETE"
299
+ });
300
+ }
301
+ };
302
+ var AgentsAPI = class {
303
+ constructor(client) {
304
+ this.client = client;
305
+ }
306
+ async list(params) {
307
+ const searchParams = new URLSearchParams();
308
+ if (params?.limit) searchParams.set("limit", String(params.limit));
309
+ if (params?.cursor) searchParams.set("cursor", params.cursor);
310
+ const query = searchParams.toString();
311
+ const response = await this.client._fetch(`/v1/agents${query ? `?${query}` : ""}`);
312
+ return response.json();
313
+ }
314
+ async get(id) {
315
+ const response = await this.client._fetch(`/v1/agents/${encodeURIComponent(id)}`);
316
+ return response.json();
317
+ }
318
+ async update(id, params) {
319
+ const response = await this.client._fetch(`/v1/agents/${encodeURIComponent(id)}`, {
320
+ method: "PATCH",
321
+ body: JSON.stringify(params)
322
+ });
323
+ return response.json();
324
+ }
325
+ };
326
+ var UsageAPI = class {
327
+ constructor(client) {
328
+ this.client = client;
329
+ }
330
+ async get(days) {
331
+ const query = days ? `?days=${days}` : "";
332
+ const response = await this.client._fetch(`/v1/usage${query}`);
333
+ return response.json();
334
+ }
335
+ };
336
+ export {
337
+ AuthenticationError,
338
+ JourneyHiveClient,
339
+ JourneyHiveError,
340
+ NotFoundError,
341
+ PermissionError,
342
+ RateLimitError,
343
+ parseErrorResponse
344
+ };
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@journeyrewards/hive-sdk",
3
+ "version": "1.0.0",
4
+ "description": "TypeScript SDK for the Journey Hive Agent Orchestration API",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.mjs",
11
+ "require": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean",
21
+ "prepublishOnly": "npm run build"
22
+ },
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "https://github.com/journeyrewards/hive-sdk"
26
+ },
27
+ "homepage": "https://journey-hive.replit.app/api-docs",
28
+ "bugs": {
29
+ "url": "https://github.com/journeyrewards/hive-sdk/issues"
30
+ },
31
+ "license": "MIT",
32
+ "keywords": [
33
+ "journeyrewards",
34
+ "journey-hive",
35
+ "ai-agents",
36
+ "agent-orchestration",
37
+ "sdk",
38
+ "openclaw",
39
+ "hospitality"
40
+ ],
41
+ "engines": {
42
+ "node": ">=18"
43
+ },
44
+ "devDependencies": {
45
+ "tsup": "^8.0.0",
46
+ "typescript": "^5.4.0"
47
+ }
48
+ }