@upstash/qstash 2.6.4-workflow-alpha.2 → 2.6.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.
@@ -1,484 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2;// src/receiver.ts
2
- var _jose = require('jose'); var jose = _interopRequireWildcard(_jose);
3
- var _cryptojs = require('crypto-js'); var _cryptojs2 = _interopRequireDefault(_cryptojs);
4
- var SignatureError = class extends Error {
5
- constructor(message) {
6
- super(message);
7
- this.name = "SignatureError";
8
- }
9
- };
10
- var Receiver = class {
11
-
12
-
13
- constructor(config) {
14
- this.currentSigningKey = config.currentSigningKey;
15
- this.nextSigningKey = config.nextSigningKey;
16
- }
17
- /**
18
- * Verify the signature of a request.
19
- *
20
- * Tries to verify the signature with the current signing key.
21
- * If that fails, maybe because you have rotated the keys recently, it will
22
- * try to verify the signature with the next signing key.
23
- *
24
- * If that fails, the signature is invalid and a `SignatureError` is thrown.
25
- */
26
- async verify(request) {
27
- const isValid = await this.verifyWithKey(this.currentSigningKey, request);
28
- if (isValid) {
29
- return true;
30
- }
31
- return this.verifyWithKey(this.nextSigningKey, request);
32
- }
33
- /**
34
- * Verify signature with a specific signing key
35
- */
36
- async verifyWithKey(key, request) {
37
- const jwt = await jose.jwtVerify(request.signature, new TextEncoder().encode(key), {
38
- issuer: "Upstash",
39
- clockTolerance: request.clockTolerance
40
- }).catch((error) => {
41
- throw new SignatureError(error.message);
42
- });
43
- const p = jwt.payload;
44
- if (request.url !== void 0 && p.sub !== request.url) {
45
- throw new SignatureError(`invalid subject: ${p.sub}, want: ${request.url}`);
46
- }
47
- const bodyHash = _cryptojs2.default.SHA256(request.body).toString(_cryptojs2.default.enc.Base64url);
48
- const padding = new RegExp(/=+$/);
49
- if (p.body.replace(padding, "") !== bodyHash.replace(padding, "")) {
50
- throw new SignatureError(`body hash does not match, want: ${p.body}, got: ${bodyHash}`);
51
- }
52
- return true;
53
- }
54
- };
55
-
56
- // src/client/error.ts
57
- var QstashError = class extends Error {
58
- constructor(message) {
59
- super(message);
60
- this.name = "QstashError";
61
- }
62
- };
63
- var QstashRatelimitError = class extends QstashError {
64
-
65
-
66
-
67
- constructor(args) {
68
- super(`Exceeded burst rate limit. ${JSON.stringify(args)} `);
69
- this.name = "QstashRatelimitError";
70
- this.limit = args.limit;
71
- this.remaining = args.remaining;
72
- this.reset = args.reset;
73
- }
74
- };
75
- var QstashChatRatelimitError = class extends QstashError {
76
-
77
-
78
-
79
-
80
-
81
-
82
- constructor(args) {
83
- super(`Exceeded chat rate limit. ${JSON.stringify(args)} `);
84
- this.limitRequests = args["limit-requests"];
85
- this.limitTokens = args["limit-tokens"];
86
- this.remainingRequests = args["remaining-requests"];
87
- this.remainingTokens = args["remaining-tokens"];
88
- this.resetRequests = args["reset-requests"];
89
- this.resetTokens = args["reset-tokens"];
90
- }
91
- };
92
- var QstashDailyRatelimitError = class extends QstashError {
93
-
94
-
95
-
96
- constructor(args) {
97
- super(`Exceeded daily rate limit. ${JSON.stringify(args)} `);
98
- this.limit = args.limit;
99
- this.remaining = args.remaining;
100
- this.reset = args.reset;
101
- this.name = "QstashChatRatelimitError";
102
- }
103
- };
104
- var QstashWorkflowError = class extends QstashError {
105
- constructor(message) {
106
- super(message);
107
- this.name = "QstashWorkflowError";
108
- }
109
- };
110
- var QstashWorkflowAbort = class extends Error {
111
-
112
-
113
- constructor(stepName, stepInfo) {
114
- super(`Aborting workflow after executing step '${stepName}'.`);
115
- this.name = "QstashWorkflowAbort";
116
- this.stepName = stepName;
117
- this.stepInfo = stepInfo;
118
- }
119
- };
120
-
121
- // src/client/llm/chat.ts
122
- var Chat = (_class = class _Chat {
123
-
124
-
125
- constructor(http, token) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);
126
- this.http = http;
127
- this.token = token;
128
- }
129
- static toChatRequest(request) {
130
- const messages = [];
131
- messages.push(
132
- { role: "system", content: request.system },
133
- { role: "user", content: request.user }
134
- );
135
- const chatRequest = { ...request, messages };
136
- return chatRequest;
137
- }
138
- /**
139
- * Calls the Upstash completions api given a ChatRequest.
140
- *
141
- * Returns a ChatCompletion or a stream of ChatCompletionChunks
142
- * if stream is enabled.
143
- *
144
- * @param request ChatRequest with messages
145
- * @returns Chat completion or stream
146
- */
147
- __init() {this.create = async (request) => {
148
- if (request.provider.owner != "upstash")
149
- return this.createThirdParty(request);
150
- const body = JSON.stringify(request);
151
- if ("stream" in request && request.stream) {
152
- return this.http.requestStream({
153
- path: ["llm", "v1", "chat", "completions"],
154
- method: "POST",
155
- headers: {
156
- "Content-Type": "application/json",
157
- Connection: "keep-alive",
158
- Accept: "text/event-stream",
159
- "Cache-Control": "no-cache",
160
- Authorization: `Bearer ${this.token}`
161
- },
162
- body
163
- });
164
- }
165
- return this.http.request({
166
- path: ["llm", "v1", "chat", "completions"],
167
- method: "POST",
168
- headers: { "Content-Type": "application/json", Authorization: `Bearer ${this.token}` },
169
- body
170
- });
171
- }}
172
- /**
173
- * Calls the Upstash completions api given a ChatRequest.
174
- *
175
- * Returns a ChatCompletion or a stream of ChatCompletionChunks
176
- * if stream is enabled.
177
- *
178
- * @param request ChatRequest with messages
179
- * @returns Chat completion or stream
180
- */
181
- __init2() {this.createThirdParty = async (request) => {
182
- const { baseUrl, token, owner } = request.provider;
183
- if (owner === "upstash")
184
- throw new Error("Upstash is not 3rd party provider!");
185
- delete request.provider;
186
- delete request.system;
187
- const body = JSON.stringify(request);
188
- if ("stream" in request && request.stream) {
189
- return this.http.requestStream({
190
- path: ["v1", "chat", "completions"],
191
- method: "POST",
192
- headers: {
193
- "Content-Type": "application/json",
194
- Connection: "keep-alive",
195
- Accept: "text/event-stream",
196
- "Cache-Control": "no-cache",
197
- Authorization: `Bearer ${token}`
198
- },
199
- body,
200
- baseUrl
201
- });
202
- }
203
- return this.http.request({
204
- path: ["v1", "chat", "completions"],
205
- method: "POST",
206
- headers: {
207
- "Content-Type": "application/json",
208
- Authorization: `Bearer ${token}`
209
- },
210
- body,
211
- baseUrl
212
- });
213
- }}
214
- /**
215
- * Calls the Upstash completions api given a PromptRequest.
216
- *
217
- * Returns a ChatCompletion or a stream of ChatCompletionChunks
218
- * if stream is enabled.
219
- *
220
- * @param request PromptRequest with system and user messages.
221
- * Note that system parameter shouldn't be passed in the case of
222
- * mistralai/Mistral-7B-Instruct-v0.2 model.
223
- * @returns Chat completion or stream
224
- */
225
- __init3() {this.prompt = async (request) => {
226
- const chatRequest = _Chat.toChatRequest(request);
227
- return this.create(chatRequest);
228
- }}
229
- }, _class);
230
-
231
- // src/client/messages.ts
232
- var Messages = class {
233
-
234
- constructor(http) {
235
- this.http = http;
236
- }
237
- /**
238
- * Get a message
239
- */
240
- async get(messageId) {
241
- const messagePayload = await this.http.request({
242
- method: "GET",
243
- path: ["v2", "messages", messageId]
244
- });
245
- const message = {
246
- ...messagePayload,
247
- urlGroup: messagePayload.topicName
248
- };
249
- return message;
250
- }
251
- /**
252
- * Cancel a message
253
- */
254
- async delete(messageId) {
255
- return await this.http.request({
256
- method: "DELETE",
257
- path: ["v2", "messages", messageId],
258
- parseResponseAsJson: false
259
- });
260
- }
261
- async deleteMany(messageIds) {
262
- const result = await this.http.request({
263
- method: "DELETE",
264
- path: ["v2", "messages"],
265
- headers: { "Content-Type": "application/json" },
266
- body: JSON.stringify({ messageIds })
267
- });
268
- return result.cancelled;
269
- }
270
- async deleteAll() {
271
- const result = await this.http.request({
272
- method: "DELETE",
273
- path: ["v2", "messages"]
274
- });
275
- return result.cancelled;
276
- }
277
- };
278
-
279
- // src/client/utils.ts
280
- var isIgnoredHeader = (header) => {
281
- const lowerCaseHeader = header.toLowerCase();
282
- return lowerCaseHeader.startsWith("content-type") || lowerCaseHeader.startsWith("upstash-");
283
- };
284
- function prefixHeaders(headers) {
285
- const keysToBePrefixed = [...headers.keys()].filter((key) => !isIgnoredHeader(key));
286
- for (const key of keysToBePrefixed) {
287
- const value = headers.get(key);
288
- if (value !== null) {
289
- headers.set(`Upstash-Forward-${key}`, value);
290
- }
291
- headers.delete(key);
292
- }
293
- return headers;
294
- }
295
- function processHeaders(request) {
296
- const headers = prefixHeaders(new Headers(request.headers));
297
- headers.set("Upstash-Method", _nullishCoalesce(request.method, () => ( "POST")));
298
- if (request.delay !== void 0) {
299
- headers.set("Upstash-Delay", `${request.delay.toFixed(0)}s`);
300
- }
301
- if (request.notBefore !== void 0) {
302
- headers.set("Upstash-Not-Before", request.notBefore.toFixed(0));
303
- }
304
- if (request.deduplicationId !== void 0) {
305
- headers.set("Upstash-Deduplication-Id", request.deduplicationId);
306
- }
307
- if (request.contentBasedDeduplication !== void 0) {
308
- headers.set("Upstash-Content-Based-Deduplication", "true");
309
- }
310
- if (request.retries !== void 0) {
311
- headers.set("Upstash-Retries", request.retries.toFixed(0));
312
- }
313
- if (request.callback !== void 0) {
314
- headers.set("Upstash-Callback", request.callback);
315
- }
316
- if (request.failureCallback !== void 0) {
317
- headers.set("Upstash-Failure-Callback", request.failureCallback);
318
- }
319
- if (request.timeout !== void 0) {
320
- headers.set("Upstash-Timeout", `${request.timeout}s`);
321
- }
322
- return headers;
323
- }
324
- function getRequestPath(request) {
325
- return _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(request.url, () => ( request.urlGroup)), () => ( request.topic)), () => ( `api/${_optionalChain([request, 'access', _ => _.api, 'optionalAccess', _2 => _2.name])}`));
326
- }
327
-
328
- // src/client/schedules.ts
329
- var Schedules = class {
330
-
331
- constructor(http) {
332
- this.http = http;
333
- }
334
- /**
335
- * Create a schedule
336
- */
337
- async create(request) {
338
- const headers = prefixHeaders(new Headers(request.headers));
339
- if (!headers.has("Content-Type")) {
340
- headers.set("Content-Type", "application/json");
341
- }
342
- headers.set("Upstash-Cron", request.cron);
343
- if (request.method !== void 0) {
344
- headers.set("Upstash-Method", request.method);
345
- }
346
- if (request.delay !== void 0) {
347
- headers.set("Upstash-Delay", `${request.delay.toFixed(0)}s`);
348
- }
349
- if (request.retries !== void 0) {
350
- headers.set("Upstash-Retries", request.retries.toFixed(0));
351
- }
352
- if (request.callback !== void 0) {
353
- headers.set("Upstash-Callback", request.callback);
354
- }
355
- if (request.failureCallback !== void 0) {
356
- headers.set("Upstash-Failure-Callback", request.failureCallback);
357
- }
358
- if (request.timeout !== void 0) {
359
- headers.set("Upstash-Timeout", `${request.timeout}s`);
360
- }
361
- return await this.http.request({
362
- method: "POST",
363
- headers,
364
- path: ["v2", "schedules", request.destination],
365
- body: request.body
366
- });
367
- }
368
- /**
369
- * Get a schedule
370
- */
371
- async get(scheduleId) {
372
- return await this.http.request({
373
- method: "GET",
374
- path: ["v2", "schedules", scheduleId]
375
- });
376
- }
377
- /**
378
- * List your schedules
379
- */
380
- async list() {
381
- return await this.http.request({
382
- method: "GET",
383
- path: ["v2", "schedules"]
384
- });
385
- }
386
- /**
387
- * Delete a schedule
388
- */
389
- async delete(scheduleId) {
390
- return await this.http.request({
391
- method: "DELETE",
392
- path: ["v2", "schedules", scheduleId],
393
- parseResponseAsJson: false
394
- });
395
- }
396
- /**
397
- * Pauses the schedule.
398
- *
399
- * A paused schedule will not deliver messages until
400
- * it is resumed.
401
- */
402
- async pause({ schedule }) {
403
- await this.http.request({
404
- method: "PATCH",
405
- path: ["v2", "schedules", schedule, "pause"],
406
- parseResponseAsJson: false
407
- });
408
- }
409
- /**
410
- * Resumes the schedule.
411
- */
412
- async resume({ schedule }) {
413
- await this.http.request({
414
- method: "PATCH",
415
- path: ["v2", "schedules", schedule, "resume"],
416
- parseResponseAsJson: false
417
- });
418
- }
419
- };
420
-
421
- // src/client/url-groups.ts
422
- var UrlGroups = class {
423
-
424
- constructor(http) {
425
- this.http = http;
426
- }
427
- /**
428
- * Create a new url group with the given name and endpoints
429
- */
430
- async addEndpoints(request) {
431
- await this.http.request({
432
- method: "POST",
433
- path: ["v2", "topics", request.name, "endpoints"],
434
- headers: { "Content-Type": "application/json" },
435
- body: JSON.stringify({ endpoints: request.endpoints }),
436
- parseResponseAsJson: false
437
- });
438
- }
439
- /**
440
- * Remove endpoints from a url group.
441
- */
442
- async removeEndpoints(request) {
443
- await this.http.request({
444
- method: "DELETE",
445
- path: ["v2", "topics", request.name, "endpoints"],
446
- headers: { "Content-Type": "application/json" },
447
- body: JSON.stringify({ endpoints: request.endpoints }),
448
- parseResponseAsJson: false
449
- });
450
- }
451
- /**
452
- * Get a list of all url groups.
453
- */
454
- async list() {
455
- return await this.http.request({
456
- method: "GET",
457
- path: ["v2", "topics"]
458
- });
459
- }
460
- /**
461
- * Get a single url group
462
- */
463
- async get(name) {
464
- return await this.http.request({
465
- method: "GET",
466
- path: ["v2", "topics", name]
467
- });
468
- }
469
- /**
470
- * Delete a url group
471
- */
472
- async delete(name) {
473
- return await this.http.request({
474
- method: "DELETE",
475
- path: ["v2", "topics", name],
476
- parseResponseAsJson: false
477
- });
478
- }
479
- };
480
-
481
- // src/client/dlq.ts
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2;// src/client/dlq.ts
482
2
  var DLQ = class {
483
3
 
484
4
  constructor(http) {
@@ -489,15 +9,15 @@ var DLQ = class {
489
9
  */
490
10
  async listMessages(options) {
491
11
  const filterPayload = {
492
- ..._optionalChain([options, 'optionalAccess', _3 => _3.filter]),
493
- topicName: _optionalChain([options, 'optionalAccess', _4 => _4.filter, 'optionalAccess', _5 => _5.urlGroup])
12
+ ..._optionalChain([options, 'optionalAccess', _ => _.filter]),
13
+ topicName: _optionalChain([options, 'optionalAccess', _2 => _2.filter, 'optionalAccess', _3 => _3.urlGroup])
494
14
  };
495
15
  const messagesPayload = await this.http.request({
496
16
  method: "GET",
497
17
  path: ["v2", "dlq"],
498
18
  query: {
499
- cursor: _optionalChain([options, 'optionalAccess', _6 => _6.cursor]),
500
- count: _optionalChain([options, 'optionalAccess', _7 => _7.count]),
19
+ cursor: _optionalChain([options, 'optionalAccess', _4 => _4.cursor]),
20
+ count: _optionalChain([options, 'optionalAccess', _5 => _5.count]),
501
21
  ...filterPayload
502
22
  }
503
23
  });
@@ -535,13 +55,60 @@ var DLQ = class {
535
55
  }
536
56
  };
537
57
 
58
+ // src/client/error.ts
59
+ var QstashError = class extends Error {
60
+ constructor(message) {
61
+ super(message);
62
+ this.name = "QstashError";
63
+ }
64
+ };
65
+ var QstashRatelimitError = class extends QstashError {
66
+
67
+
68
+
69
+ constructor(args) {
70
+ super(`Exceeded burst rate limit. ${JSON.stringify(args)} `);
71
+ this.limit = args.limit;
72
+ this.remaining = args.remaining;
73
+ this.reset = args.reset;
74
+ }
75
+ };
76
+ var QstashChatRatelimitError = class extends QstashError {
77
+
78
+
79
+
80
+
81
+
82
+
83
+ constructor(args) {
84
+ super(`Exceeded chat rate limit. ${JSON.stringify(args)} `);
85
+ this.limitRequests = args["limit-requests"];
86
+ this.limitTokens = args["limit-tokens"];
87
+ this.remainingRequests = args["remaining-requests"];
88
+ this.remainingTokens = args["remaining-tokens"];
89
+ this.resetRequests = args["reset-requests"];
90
+ this.resetTokens = args["reset-tokens"];
91
+ }
92
+ };
93
+ var QstashDailyRatelimitError = class extends QstashError {
94
+
95
+
96
+
97
+ constructor(args) {
98
+ super(`Exceeded daily rate limit. ${JSON.stringify(args)} `);
99
+ this.limit = args.limit;
100
+ this.remaining = args.remaining;
101
+ this.reset = args.reset;
102
+ }
103
+ };
104
+
538
105
  // src/client/http.ts
539
- var HttpClient = (_class2 = class {
106
+ var HttpClient = (_class = class {
540
107
 
541
108
 
542
109
 
543
110
 
544
- constructor(config) {;_class2.prototype.__init4.call(this);_class2.prototype.__init5.call(this);
111
+ constructor(config) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);
545
112
  this.baseUrl = config.baseUrl.replace(/\/$/, "");
546
113
  this.authorization = config.authorization;
547
114
  this.retry = // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
@@ -549,8 +116,8 @@ var HttpClient = (_class2 = class {
549
116
  attempts: 1,
550
117
  backoff: () => 0
551
118
  } : {
552
- attempts: _optionalChain([config, 'access', _8 => _8.retry, 'optionalAccess', _9 => _9.retries]) ? config.retry.retries + 1 : 5,
553
- backoff: _nullishCoalesce(_optionalChain([config, 'access', _10 => _10.retry, 'optionalAccess', _11 => _11.backoff]), () => ( ((retryCount) => Math.exp(retryCount) * 50)))
119
+ attempts: _optionalChain([config, 'access', _6 => _6.retry, 'optionalAccess', _7 => _7.retries]) ? config.retry.retries + 1 : 5,
120
+ backoff: _nullishCoalesce(_optionalChain([config, 'access', _8 => _8.retry, 'optionalAccess', _9 => _9.backoff]), () => ( ((retryCount) => Math.exp(retryCount) * 50)))
554
121
  };
555
122
  }
556
123
  async request(request) {
@@ -590,7 +157,7 @@ var HttpClient = (_class2 = class {
590
157
  await reader.cancel();
591
158
  }
592
159
  }
593
- __init4() {this.requestWithBackoff = async (request) => {
160
+ __init() {this.requestWithBackoff = async (request) => {
594
161
  const [url, requestOptions] = this.processRequest(request);
595
162
  let response = void 0;
596
163
  let error = void 0;
@@ -612,7 +179,7 @@ var HttpClient = (_class2 = class {
612
179
  error
613
180
  };
614
181
  }}
615
- __init5() {this.processRequest = (request) => {
182
+ __init2() {this.processRequest = (request) => {
616
183
  const headers = new Headers(request.headers);
617
184
  if (!headers.has("Authorization")) {
618
185
  headers.set("Authorization", this.authorization);
@@ -662,30 +229,351 @@ var HttpClient = (_class2 = class {
662
229
  throw new QstashError(body.length > 0 ? body : `Error: status=${response.status}`);
663
230
  }
664
231
  }
232
+ }, _class);
233
+
234
+ // src/client/llm/providers.ts
235
+ var setupAnalytics = (analytics, providerApiKey, providerBaseUrl, provider) => {
236
+ if (!analytics)
237
+ return {};
238
+ switch (analytics.name) {
239
+ case "helicone": {
240
+ switch (provider) {
241
+ case "upstash": {
242
+ return {
243
+ baseURL: "https://qstash.helicone.ai/llm/v1/chat/completions",
244
+ defaultHeaders: {
245
+ "Helicone-Auth": `Bearer ${analytics.token}`,
246
+ Authorization: `Bearer ${providerApiKey}`
247
+ }
248
+ };
249
+ }
250
+ default: {
251
+ return {
252
+ baseURL: "https://gateway.helicone.ai/v1/chat/completions",
253
+ defaultHeaders: {
254
+ "Helicone-Auth": `Bearer ${analytics.token}`,
255
+ "Helicone-Target-Url": providerBaseUrl,
256
+ Authorization: `Bearer ${providerApiKey}`
257
+ }
258
+ };
259
+ }
260
+ }
261
+ }
262
+ default: {
263
+ throw new Error("Unknown analytics provider");
264
+ }
265
+ }
266
+ };
267
+ var upstash = () => {
268
+ return {
269
+ owner: "upstash",
270
+ baseUrl: "https://qstash.upstash.io/llm",
271
+ token: ""
272
+ };
273
+ };
274
+ var openai = ({
275
+ token
276
+ }) => {
277
+ return { token, owner: "openai", baseUrl: "https://api.openai.com" };
278
+ };
279
+ var custom = ({
280
+ baseUrl,
281
+ token
282
+ }) => {
283
+ const trimmedBaseUrl = baseUrl.replace(/\/(v1\/)?chat\/completions$/, "");
284
+ return {
285
+ token,
286
+ owner: "custom",
287
+ baseUrl: trimmedBaseUrl
288
+ };
289
+ };
290
+
291
+ // src/client/llm/chat.ts
292
+ var Chat = (_class2 = class _Chat {
293
+
294
+
295
+ constructor(http, token) {;_class2.prototype.__init3.call(this);_class2.prototype.__init4.call(this);_class2.prototype.__init5.call(this);
296
+ this.http = http;
297
+ this.token = token;
298
+ }
299
+ static toChatRequest(request) {
300
+ const messages = [];
301
+ messages.push(
302
+ { role: "system", content: request.system },
303
+ { role: "user", content: request.user }
304
+ );
305
+ const chatRequest = { ...request, messages };
306
+ return chatRequest;
307
+ }
308
+ /**
309
+ * Calls the Upstash completions api given a ChatRequest.
310
+ *
311
+ * Returns a ChatCompletion or a stream of ChatCompletionChunks
312
+ * if stream is enabled.
313
+ *
314
+ * @param request ChatRequest with messages
315
+ * @returns Chat completion or stream
316
+ */
317
+ __init3() {this.create = async (request) => {
318
+ if (request.provider.owner != "upstash")
319
+ return this.createThirdParty(request);
320
+ const body = JSON.stringify(request);
321
+ let baseUrl = void 0;
322
+ let headers = {
323
+ "Content-Type": "application/json",
324
+ Authorization: `Bearer ${this.token}`,
325
+ ..."stream" in request && request.stream ? {
326
+ Connection: "keep-alive",
327
+ Accept: "text/event-stream",
328
+ "Cache-Control": "no-cache"
329
+ } : {}
330
+ };
331
+ if (request.analytics) {
332
+ const { baseURL, defaultHeaders } = setupAnalytics(
333
+ { name: "helicone", token: request.analytics.token },
334
+ this.getAuthorizationToken(),
335
+ request.provider.baseUrl,
336
+ "upstash"
337
+ );
338
+ headers = { ...headers, ...defaultHeaders };
339
+ baseUrl = baseURL;
340
+ }
341
+ const path = request.analytics ? [] : ["llm", "v1", "chat", "completions"];
342
+ return "stream" in request && request.stream ? this.http.requestStream({
343
+ path,
344
+ method: "POST",
345
+ headers,
346
+ baseUrl,
347
+ body
348
+ }) : this.http.request({
349
+ path,
350
+ method: "POST",
351
+ headers,
352
+ baseUrl,
353
+ body
354
+ });
355
+ }}
356
+ /**
357
+ * Calls the Upstash completions api given a ChatRequest.
358
+ *
359
+ * Returns a ChatCompletion or a stream of ChatCompletionChunks
360
+ * if stream is enabled.
361
+ *
362
+ * @param request ChatRequest with messages
363
+ * @returns Chat completion or stream
364
+ */
365
+ // eslint-disable-next-line @typescript-eslint/require-await
366
+ __init4() {this.createThirdParty = async (request) => {
367
+ const { baseUrl, token, owner } = request.provider;
368
+ if (owner === "upstash")
369
+ throw new Error("Upstash is not 3rd party provider!");
370
+ delete request.provider;
371
+ delete request.system;
372
+ const analytics = request.analytics;
373
+ delete request.analytics;
374
+ const body = JSON.stringify(request);
375
+ const isAnalyticsEnabled = _optionalChain([analytics, 'optionalAccess', _12 => _12.name]) && analytics.token;
376
+ const analyticsConfig = _optionalChain([analytics, 'optionalAccess', _13 => _13.name]) && analytics.token ? setupAnalytics({ name: analytics.name, token: analytics.token }, token, baseUrl, owner) : { defaultHeaders: void 0, baseURL: baseUrl };
377
+ const isStream = "stream" in request && request.stream;
378
+ const headers = {
379
+ "Content-Type": "application/json",
380
+ Authorization: `Bearer ${token}`,
381
+ ...isStream ? {
382
+ Connection: "keep-alive",
383
+ Accept: "text/event-stream",
384
+ "Cache-Control": "no-cache"
385
+ } : {},
386
+ ...analyticsConfig.defaultHeaders
387
+ };
388
+ const response = await this.http[isStream ? "requestStream" : "request"]({
389
+ path: isAnalyticsEnabled ? [] : ["v1", "chat", "completions"],
390
+ method: "POST",
391
+ headers,
392
+ body,
393
+ baseUrl: analyticsConfig.baseURL
394
+ });
395
+ return response;
396
+ }}
397
+ // Helper method to get the authorization token
398
+ getAuthorizationToken() {
399
+ const authHeader = String(this.http.authorization);
400
+ const match = authHeader.match(/Bearer (.+)/);
401
+ if (!match) {
402
+ throw new Error("Invalid authorization header format");
403
+ }
404
+ return match[1];
405
+ }
406
+ /**
407
+ * Calls the Upstash completions api given a PromptRequest.
408
+ *
409
+ * Returns a ChatCompletion or a stream of ChatCompletionChunks
410
+ * if stream is enabled.
411
+ *
412
+ * @param request PromptRequest with system and user messages.
413
+ * Note that system parameter shouldn't be passed in the case of
414
+ * mistralai/Mistral-7B-Instruct-v0.2 model.
415
+ * @returns Chat completion or stream
416
+ */
417
+ __init5() {this.prompt = async (request) => {
418
+ const chatRequest = _Chat.toChatRequest(request);
419
+ return this.create(chatRequest);
420
+ }}
665
421
  }, _class2);
666
422
 
667
423
  // src/client/llm/utils.ts
668
- function appendLLMOptionsIfNeeded(request, headers) {
669
- if (_optionalChain([request, 'access', _12 => _12.api, 'optionalAccess', _13 => _13.provider, 'optionalAccess', _14 => _14.owner]) === "upstash") {
670
- request.api = { name: "llm" };
424
+ function appendLLMOptionsIfNeeded(request, headers, http) {
425
+ if (!request.api)
426
+ return;
427
+ const provider = request.api.provider;
428
+ const analytics = request.api.analytics;
429
+ if (_optionalChain([provider, 'optionalAccess', _14 => _14.owner]) === "upstash") {
430
+ handleUpstashProvider(request, headers, http, analytics);
431
+ return;
432
+ }
433
+ if (!("provider" in request.api))
671
434
  return;
435
+ const { baseUrl, token } = validateProviderConfig(provider);
436
+ const analyticsConfig = analytics ? setupAnalytics({ name: analytics.name, token: analytics.token }, token, baseUrl, "custom") : void 0;
437
+ if (analyticsConfig) {
438
+ setAnalyticsHeaders(headers, analyticsConfig);
439
+ request.url = analyticsConfig.baseURL;
440
+ } else {
441
+ request.url = `${baseUrl}/v1/chat/completions`;
442
+ headers.set("Authorization", `Bearer ${token}`);
672
443
  }
673
- if (request.api && "provider" in request.api) {
674
- const provider = request.api.provider;
675
- if (!_optionalChain([provider, 'optionalAccess', _15 => _15.baseUrl]))
676
- throw new Error("baseUrl cannot be empty or undefined!");
677
- if (!provider.token)
678
- throw new Error("token cannot be empty or undefined!");
679
- request.url = `${provider.baseUrl}/v1/chat/completions`;
680
- headers.set("Authorization", `Bearer ${provider.token}`);
444
+ }
445
+ function handleUpstashProvider(request, headers, http, analytics) {
446
+ if (analytics) {
447
+ const analyticsConfig = setupAnalytics(
448
+ { name: analytics.name, token: analytics.token },
449
+ //@ts-expect-error hacky way to get bearer token
450
+ String(http.authorization).split("Bearer ")[1],
451
+ _optionalChain([request, 'access', _15 => _15.api, 'optionalAccess', _16 => _16.provider, 'optionalAccess', _17 => _17.baseUrl]),
452
+ "upstash"
453
+ );
454
+ setAnalyticsHeaders(headers, analyticsConfig);
455
+ request.url = analyticsConfig.baseURL;
456
+ } else {
457
+ request.api = { name: "llm" };
458
+ }
459
+ }
460
+ function validateProviderConfig(provider) {
461
+ if (!_optionalChain([provider, 'optionalAccess', _18 => _18.baseUrl]))
462
+ throw new Error("baseUrl cannot be empty or undefined!");
463
+ if (!provider.token)
464
+ throw new Error("token cannot be empty or undefined!");
465
+ return { baseUrl: provider.baseUrl, token: provider.token };
466
+ }
467
+ function setAnalyticsHeaders(headers, analyticsConfig) {
468
+ headers.set("Helicone-Auth", _nullishCoalesce(_optionalChain([analyticsConfig, 'access', _19 => _19.defaultHeaders, 'optionalAccess', _20 => _20["Helicone-Auth"]]), () => ( "")));
469
+ headers.set("Authorization", _nullishCoalesce(_optionalChain([analyticsConfig, 'access', _21 => _21.defaultHeaders, 'optionalAccess', _22 => _22.Authorization]), () => ( "")));
470
+ if (_optionalChain([analyticsConfig, 'access', _23 => _23.defaultHeaders, 'optionalAccess', _24 => _24["Helicone-Target-Url"]])) {
471
+ headers.set("Helicone-Target-Url", analyticsConfig.defaultHeaders["Helicone-Target-Url"]);
681
472
  }
682
473
  }
683
474
  function ensureCallbackPresent(request) {
684
- if (_optionalChain([request, 'access', _16 => _16.api, 'optionalAccess', _17 => _17.name]) === "llm" && !request.callback) {
475
+ if (_optionalChain([request, 'access', _25 => _25.api, 'optionalAccess', _26 => _26.name]) === "llm" && !request.callback) {
685
476
  throw new TypeError("Callback cannot be undefined when using LLM");
686
477
  }
687
478
  }
688
479
 
480
+ // src/client/messages.ts
481
+ var Messages = class {
482
+
483
+ constructor(http) {
484
+ this.http = http;
485
+ }
486
+ /**
487
+ * Get a message
488
+ */
489
+ async get(messageId) {
490
+ const messagePayload = await this.http.request({
491
+ method: "GET",
492
+ path: ["v2", "messages", messageId]
493
+ });
494
+ const message = {
495
+ ...messagePayload,
496
+ urlGroup: messagePayload.topicName
497
+ };
498
+ return message;
499
+ }
500
+ /**
501
+ * Cancel a message
502
+ */
503
+ async delete(messageId) {
504
+ return await this.http.request({
505
+ method: "DELETE",
506
+ path: ["v2", "messages", messageId],
507
+ parseResponseAsJson: false
508
+ });
509
+ }
510
+ async deleteMany(messageIds) {
511
+ const result = await this.http.request({
512
+ method: "DELETE",
513
+ path: ["v2", "messages"],
514
+ headers: { "Content-Type": "application/json" },
515
+ body: JSON.stringify({ messageIds })
516
+ });
517
+ return result.cancelled;
518
+ }
519
+ async deleteAll() {
520
+ const result = await this.http.request({
521
+ method: "DELETE",
522
+ path: ["v2", "messages"]
523
+ });
524
+ return result.cancelled;
525
+ }
526
+ };
527
+
528
+ // src/client/utils.ts
529
+ var isIgnoredHeader = (header) => {
530
+ const lowerCaseHeader = header.toLowerCase();
531
+ return lowerCaseHeader.startsWith("content-type") || lowerCaseHeader.startsWith("upstash-");
532
+ };
533
+ function prefixHeaders(headers) {
534
+ const keysToBePrefixed = [...headers.keys()].filter((key) => !isIgnoredHeader(key));
535
+ for (const key of keysToBePrefixed) {
536
+ const value = headers.get(key);
537
+ if (value !== null) {
538
+ headers.set(`Upstash-Forward-${key}`, value);
539
+ }
540
+ headers.delete(key);
541
+ }
542
+ return headers;
543
+ }
544
+ function processHeaders(request) {
545
+ const headers = prefixHeaders(new Headers(request.headers));
546
+ headers.set("Upstash-Method", _nullishCoalesce(request.method, () => ( "POST")));
547
+ if (request.delay !== void 0) {
548
+ headers.set("Upstash-Delay", `${request.delay.toFixed(0)}s`);
549
+ }
550
+ if (request.notBefore !== void 0) {
551
+ headers.set("Upstash-Not-Before", request.notBefore.toFixed(0));
552
+ }
553
+ if (request.deduplicationId !== void 0) {
554
+ headers.set("Upstash-Deduplication-Id", request.deduplicationId);
555
+ }
556
+ if (request.contentBasedDeduplication !== void 0) {
557
+ headers.set("Upstash-Content-Based-Deduplication", "true");
558
+ }
559
+ if (request.retries !== void 0) {
560
+ headers.set("Upstash-Retries", request.retries.toFixed(0));
561
+ }
562
+ if (request.callback !== void 0) {
563
+ headers.set("Upstash-Callback", request.callback);
564
+ }
565
+ if (request.failureCallback !== void 0) {
566
+ headers.set("Upstash-Failure-Callback", request.failureCallback);
567
+ }
568
+ if (request.timeout !== void 0) {
569
+ headers.set("Upstash-Timeout", `${request.timeout}s`);
570
+ }
571
+ return headers;
572
+ }
573
+ function getRequestPath(request) {
574
+ return _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(request.url, () => ( request.urlGroup)), () => ( request.topic)), () => ( `api/${_optionalChain([request, 'access', _27 => _27.api, 'optionalAccess', _28 => _28.name])}`));
575
+ }
576
+
689
577
  // src/client/queue.ts
690
578
  var Queue = class {
691
579
 
@@ -774,7 +662,7 @@ var Queue = class {
774
662
  const headers = prefixHeaders(new Headers(request.headers));
775
663
  headers.set("Content-Type", "application/json");
776
664
  ensureCallbackPresent(request);
777
- appendLLMOptionsIfNeeded(request, headers);
665
+ appendLLMOptionsIfNeeded(request, headers, this.http);
778
666
  const response = await this.enqueue({
779
667
  ...request,
780
668
  body: JSON.stringify(request.body),
@@ -813,6 +701,159 @@ var Queue = class {
813
701
  }
814
702
  };
815
703
 
704
+ // src/client/schedules.ts
705
+ var Schedules = class {
706
+
707
+ constructor(http) {
708
+ this.http = http;
709
+ }
710
+ /**
711
+ * Create a schedule
712
+ */
713
+ async create(request) {
714
+ const headers = prefixHeaders(new Headers(request.headers));
715
+ if (!headers.has("Content-Type")) {
716
+ headers.set("Content-Type", "application/json");
717
+ }
718
+ headers.set("Upstash-Cron", request.cron);
719
+ if (request.method !== void 0) {
720
+ headers.set("Upstash-Method", request.method);
721
+ }
722
+ if (request.delay !== void 0) {
723
+ headers.set("Upstash-Delay", `${request.delay.toFixed(0)}s`);
724
+ }
725
+ if (request.retries !== void 0) {
726
+ headers.set("Upstash-Retries", request.retries.toFixed(0));
727
+ }
728
+ if (request.callback !== void 0) {
729
+ headers.set("Upstash-Callback", request.callback);
730
+ }
731
+ if (request.failureCallback !== void 0) {
732
+ headers.set("Upstash-Failure-Callback", request.failureCallback);
733
+ }
734
+ if (request.timeout !== void 0) {
735
+ headers.set("Upstash-Timeout", `${request.timeout}s`);
736
+ }
737
+ return await this.http.request({
738
+ method: "POST",
739
+ headers,
740
+ path: ["v2", "schedules", request.destination],
741
+ body: request.body
742
+ });
743
+ }
744
+ /**
745
+ * Get a schedule
746
+ */
747
+ async get(scheduleId) {
748
+ return await this.http.request({
749
+ method: "GET",
750
+ path: ["v2", "schedules", scheduleId]
751
+ });
752
+ }
753
+ /**
754
+ * List your schedules
755
+ */
756
+ async list() {
757
+ return await this.http.request({
758
+ method: "GET",
759
+ path: ["v2", "schedules"]
760
+ });
761
+ }
762
+ /**
763
+ * Delete a schedule
764
+ */
765
+ async delete(scheduleId) {
766
+ return await this.http.request({
767
+ method: "DELETE",
768
+ path: ["v2", "schedules", scheduleId],
769
+ parseResponseAsJson: false
770
+ });
771
+ }
772
+ /**
773
+ * Pauses the schedule.
774
+ *
775
+ * A paused schedule will not deliver messages until
776
+ * it is resumed.
777
+ */
778
+ async pause({ schedule }) {
779
+ await this.http.request({
780
+ method: "PATCH",
781
+ path: ["v2", "schedules", schedule, "pause"],
782
+ parseResponseAsJson: false
783
+ });
784
+ }
785
+ /**
786
+ * Resumes the schedule.
787
+ */
788
+ async resume({ schedule }) {
789
+ await this.http.request({
790
+ method: "PATCH",
791
+ path: ["v2", "schedules", schedule, "resume"],
792
+ parseResponseAsJson: false
793
+ });
794
+ }
795
+ };
796
+
797
+ // src/client/url-groups.ts
798
+ var UrlGroups = class {
799
+
800
+ constructor(http) {
801
+ this.http = http;
802
+ }
803
+ /**
804
+ * Create a new url group with the given name and endpoints
805
+ */
806
+ async addEndpoints(request) {
807
+ await this.http.request({
808
+ method: "POST",
809
+ path: ["v2", "topics", request.name, "endpoints"],
810
+ headers: { "Content-Type": "application/json" },
811
+ body: JSON.stringify({ endpoints: request.endpoints }),
812
+ parseResponseAsJson: false
813
+ });
814
+ }
815
+ /**
816
+ * Remove endpoints from a url group.
817
+ */
818
+ async removeEndpoints(request) {
819
+ await this.http.request({
820
+ method: "DELETE",
821
+ path: ["v2", "topics", request.name, "endpoints"],
822
+ headers: { "Content-Type": "application/json" },
823
+ body: JSON.stringify({ endpoints: request.endpoints }),
824
+ parseResponseAsJson: false
825
+ });
826
+ }
827
+ /**
828
+ * Get a list of all url groups.
829
+ */
830
+ async list() {
831
+ return await this.http.request({
832
+ method: "GET",
833
+ path: ["v2", "topics"]
834
+ });
835
+ }
836
+ /**
837
+ * Get a single url group
838
+ */
839
+ async get(name) {
840
+ return await this.http.request({
841
+ method: "GET",
842
+ path: ["v2", "topics", name]
843
+ });
844
+ }
845
+ /**
846
+ * Delete a url group
847
+ */
848
+ async delete(name) {
849
+ return await this.http.request({
850
+ method: "DELETE",
851
+ path: ["v2", "topics", name],
852
+ parseResponseAsJson: false
853
+ });
854
+ }
855
+ };
856
+
816
857
  // src/client/client.ts
817
858
  var Client = class {
818
859
 
@@ -873,7 +914,7 @@ var Client = class {
873
914
  * Create, read, update or delete queues.
874
915
  */
875
916
  queue(request) {
876
- return new Queue(this.http, _optionalChain([request, 'optionalAccess', _18 => _18.queueName]));
917
+ return new Queue(this.http, _optionalChain([request, 'optionalAccess', _29 => _29.queueName]));
877
918
  }
878
919
  /**
879
920
  * Access the Chat API
@@ -901,7 +942,7 @@ var Client = class {
901
942
  const headers = prefixHeaders(new Headers(request.headers));
902
943
  headers.set("Content-Type", "application/json");
903
944
  ensureCallbackPresent(request);
904
- appendLLMOptionsIfNeeded(request, headers);
945
+ appendLLMOptionsIfNeeded(request, headers, this.http);
905
946
  const response = await this.publish({
906
947
  ...request,
907
948
  headers,
@@ -932,8 +973,7 @@ var Client = class {
932
973
  },
933
974
  method: "POST"
934
975
  });
935
- const arrayResposne = Array.isArray(response) ? response : [response];
936
- return arrayResposne;
976
+ return response;
937
977
  }
938
978
  /**
939
979
  * Batch publish messages to QStash, serializing each body to JSON.
@@ -945,7 +985,7 @@ var Client = class {
945
985
  }
946
986
  message.headers = new Headers(message.headers);
947
987
  ensureCallbackPresent(message);
948
- appendLLMOptionsIfNeeded(message, message.headers);
988
+ appendLLMOptionsIfNeeded(message, message.headers, this.http);
949
989
  message.headers.set("Content-Type", "application/json");
950
990
  }
951
991
  const response = await this.batch(request);
@@ -972,10 +1012,10 @@ var Client = class {
972
1012
  */
973
1013
  async events(request) {
974
1014
  const query = {};
975
- if (_optionalChain([request, 'optionalAccess', _19 => _19.cursor]) && request.cursor > 0) {
1015
+ if (_optionalChain([request, 'optionalAccess', _30 => _30.cursor]) && request.cursor > 0) {
976
1016
  query.cursor = request.cursor.toString();
977
1017
  }
978
- for (const [key, value] of Object.entries(_nullishCoalesce(_optionalChain([request, 'optionalAccess', _20 => _20.filter]), () => ( {})))) {
1018
+ for (const [key, value] of Object.entries(_nullishCoalesce(_optionalChain([request, 'optionalAccess', _31 => _31.filter]), () => ( {})))) {
979
1019
  if (typeof value === "number" && value < 0) {
980
1020
  continue;
981
1021
  }
@@ -1016,4 +1056,4 @@ var Client = class {
1016
1056
 
1017
1057
 
1018
1058
 
1019
- exports.SignatureError = SignatureError; exports.Receiver = Receiver; exports.QstashError = QstashError; exports.QstashRatelimitError = QstashRatelimitError; exports.QstashChatRatelimitError = QstashChatRatelimitError; exports.QstashDailyRatelimitError = QstashDailyRatelimitError; exports.QstashWorkflowError = QstashWorkflowError; exports.QstashWorkflowAbort = QstashWorkflowAbort; exports.Chat = Chat; exports.Messages = Messages; exports.Schedules = Schedules; exports.UrlGroups = UrlGroups; exports.Client = Client;
1059
+ exports.QstashError = QstashError; exports.QstashRatelimitError = QstashRatelimitError; exports.QstashChatRatelimitError = QstashChatRatelimitError; exports.QstashDailyRatelimitError = QstashDailyRatelimitError; exports.setupAnalytics = setupAnalytics; exports.upstash = upstash; exports.openai = openai; exports.custom = custom; exports.Chat = Chat; exports.Messages = Messages; exports.Schedules = Schedules; exports.UrlGroups = UrlGroups; exports.Client = Client;