@resultdev/sdk 0.3.1 → 0.3.2
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/CHANGELOG.md +9 -0
- package/dist/{client--Xjaaw1l.d.ts → client-D5IGLPW4.d.ts} +3 -1
- package/dist/{client-BrOD2EO5.d.cts → client-N6MW9IE1.d.cts} +3 -1
- package/dist/index.cjs +107 -20
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +107 -20
- package/dist/{middleware-Uh09_lFn.d.ts → middleware-8UNqItQG.d.ts} +1 -1
- package/dist/{middleware-VCWoai4o.d.cts → middleware-CGn44ocX.d.cts} +1 -1
- package/dist/ssr/middleware.d.cts +2 -2
- package/dist/ssr/middleware.d.ts +2 -2
- package/dist/ssr.cjs +107 -20
- package/dist/ssr.d.cts +4 -4
- package/dist/ssr.d.ts +4 -4
- package/dist/ssr.js +107 -20
- package/dist/{types-BmU3deRO.d.cts → types-BTdjI7Yj.d.cts} +2 -1
- package/dist/{types-BmU3deRO.d.ts → types-BTdjI7Yj.d.ts} +2 -1
- package/package.json +13 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @resultdev/sdk
|
|
2
2
|
|
|
3
|
+
## 0.3.2
|
|
4
|
+
|
|
5
|
+
- AI calls made through the SDK now report returned token usage to the
|
|
6
|
+
matching Result app. Operations can show per-app AI usage even while the
|
|
7
|
+
upstream partnership AI counters remain unavailable.
|
|
8
|
+
- Caller AbortSignal listeners are now detached once a response body is
|
|
9
|
+
fully consumed, instead of accumulating on long-lived signals across
|
|
10
|
+
requests.
|
|
11
|
+
|
|
3
12
|
## 0.3.1
|
|
4
13
|
|
|
5
14
|
- A missing `baseUrl` now throws `MISSING_BASE_URL` at client construction
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { e as AuthSession, U as UserSchema, a as ResultConfig, G as AuthRefreshResponse, C as ChatCompletionRequest, B as ToolCall, H as Annotation, I as ImageGenerationRequest, j as EmbeddingsRequest, J as EmbeddingObject, h as CreateUserRequest, K as CreateUserResponse, o as ResultError, g as CreateSessionRequest, L as CreateSessionResponse, l as OAuthProvidersSchema, M as RefreshSessionResponse, N as GetProfileResponse, Q as SendVerificationEmailRequest, V as VerifyEmailRequest, W as VerifyEmailResponse, X as SendResetPasswordEmailRequest, Y as ExchangeResetPasswordTokenRequest, Z as ExchangeResetPasswordTokenResponse, _ as ResetPasswordResponse, $ as GetPublicAuthConfigResponse, S as SendRawEmailRequest, q as SendEmailResponse, v as SubscribeResponse, r as SocketMessage, P as PresenceMember, u as StorageFileSchema, a0 as ListObjectsResponseSchema, i as DeleteObjectsResponse, A as Analytics, w as Support } from './types-
|
|
1
|
+
import { e as AuthSession, U as UserSchema, a as ResultConfig, G as AuthRefreshResponse, C as ChatCompletionRequest, B as ToolCall, H as Annotation, I as ImageGenerationRequest, j as EmbeddingsRequest, J as EmbeddingObject, h as CreateUserRequest, K as CreateUserResponse, o as ResultError, g as CreateSessionRequest, L as CreateSessionResponse, l as OAuthProvidersSchema, M as RefreshSessionResponse, N as GetProfileResponse, Q as SendVerificationEmailRequest, V as VerifyEmailRequest, W as VerifyEmailResponse, X as SendResetPasswordEmailRequest, Y as ExchangeResetPasswordTokenRequest, Z as ExchangeResetPasswordTokenResponse, _ as ResetPasswordResponse, $ as GetPublicAuthConfigResponse, S as SendRawEmailRequest, q as SendEmailResponse, v as SubscribeResponse, r as SocketMessage, P as PresenceMember, u as StorageFileSchema, a0 as ListObjectsResponseSchema, i as DeleteObjectsResponse, A as Analytics, w as Support } from './types-BTdjI7Yj.js';
|
|
2
2
|
import * as _supabase_postgrest_js from '@supabase/postgrest-js';
|
|
3
3
|
import { PostgrestClient } from '@supabase/postgrest-js';
|
|
4
4
|
|
|
@@ -200,6 +200,8 @@ declare class HttpClient {
|
|
|
200
200
|
setRefreshToken(token: string | null): void;
|
|
201
201
|
/** Returns the current default headers including the authorization header if set. */
|
|
202
202
|
getHeaders(): Record<string, string>;
|
|
203
|
+
/** Returns the publishable project key used to identify SDK usage reports. */
|
|
204
|
+
getAnonKey(): string | undefined;
|
|
203
205
|
refreshAccessToken(): Promise<AuthRefreshResponse>;
|
|
204
206
|
/** Returns a token safe to use for a new connection handshake. */
|
|
205
207
|
getValidAccessToken(leewaySeconds?: number): Promise<string | null>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { e as AuthSession, U as UserSchema, a as ResultConfig, G as AuthRefreshResponse, C as ChatCompletionRequest, B as ToolCall, H as Annotation, I as ImageGenerationRequest, j as EmbeddingsRequest, J as EmbeddingObject, h as CreateUserRequest, K as CreateUserResponse, o as ResultError, g as CreateSessionRequest, L as CreateSessionResponse, l as OAuthProvidersSchema, M as RefreshSessionResponse, N as GetProfileResponse, Q as SendVerificationEmailRequest, V as VerifyEmailRequest, W as VerifyEmailResponse, X as SendResetPasswordEmailRequest, Y as ExchangeResetPasswordTokenRequest, Z as ExchangeResetPasswordTokenResponse, _ as ResetPasswordResponse, $ as GetPublicAuthConfigResponse, S as SendRawEmailRequest, q as SendEmailResponse, v as SubscribeResponse, r as SocketMessage, P as PresenceMember, u as StorageFileSchema, a0 as ListObjectsResponseSchema, i as DeleteObjectsResponse, A as Analytics, w as Support } from './types-
|
|
1
|
+
import { e as AuthSession, U as UserSchema, a as ResultConfig, G as AuthRefreshResponse, C as ChatCompletionRequest, B as ToolCall, H as Annotation, I as ImageGenerationRequest, j as EmbeddingsRequest, J as EmbeddingObject, h as CreateUserRequest, K as CreateUserResponse, o as ResultError, g as CreateSessionRequest, L as CreateSessionResponse, l as OAuthProvidersSchema, M as RefreshSessionResponse, N as GetProfileResponse, Q as SendVerificationEmailRequest, V as VerifyEmailRequest, W as VerifyEmailResponse, X as SendResetPasswordEmailRequest, Y as ExchangeResetPasswordTokenRequest, Z as ExchangeResetPasswordTokenResponse, _ as ResetPasswordResponse, $ as GetPublicAuthConfigResponse, S as SendRawEmailRequest, q as SendEmailResponse, v as SubscribeResponse, r as SocketMessage, P as PresenceMember, u as StorageFileSchema, a0 as ListObjectsResponseSchema, i as DeleteObjectsResponse, A as Analytics, w as Support } from './types-BTdjI7Yj.cjs';
|
|
2
2
|
import * as _supabase_postgrest_js from '@supabase/postgrest-js';
|
|
3
3
|
import { PostgrestClient } from '@supabase/postgrest-js';
|
|
4
4
|
|
|
@@ -200,6 +200,8 @@ declare class HttpClient {
|
|
|
200
200
|
setRefreshToken(token: string | null): void;
|
|
201
201
|
/** Returns the current default headers including the authorization header if set. */
|
|
202
202
|
getHeaders(): Record<string, string>;
|
|
203
|
+
/** Returns the publishable project key used to identify SDK usage reports. */
|
|
204
|
+
getAnonKey(): string | undefined;
|
|
203
205
|
refreshAccessToken(): Promise<AuthRefreshResponse>;
|
|
204
206
|
/** Returns a token safe to use for a new connection handshake. */
|
|
205
207
|
getValidAccessToken(leewaySeconds?: number): Promise<string | null>;
|
package/dist/index.cjs
CHANGED
|
@@ -602,6 +602,7 @@ var HttpClient = class {
|
|
|
602
602
|
}
|
|
603
603
|
let controller;
|
|
604
604
|
let timer;
|
|
605
|
+
let removeCallerAbortListener;
|
|
605
606
|
if (this.timeout > 0 || callerSignal) {
|
|
606
607
|
controller = new AbortController();
|
|
607
608
|
if (this.timeout > 0) {
|
|
@@ -615,16 +616,11 @@ var HttpClient = class {
|
|
|
615
616
|
callerSignal.addEventListener("abort", onCallerAbort, {
|
|
616
617
|
once: true
|
|
617
618
|
});
|
|
618
|
-
|
|
619
|
-
"abort",
|
|
620
|
-
() => {
|
|
621
|
-
callerSignal.removeEventListener("abort", onCallerAbort);
|
|
622
|
-
},
|
|
623
|
-
{ once: true }
|
|
624
|
-
);
|
|
619
|
+
removeCallerAbortListener = () => callerSignal.removeEventListener("abort", onCallerAbort);
|
|
625
620
|
}
|
|
626
621
|
}
|
|
627
622
|
}
|
|
623
|
+
let detachOnExit = true;
|
|
628
624
|
try {
|
|
629
625
|
const response = await this.fetch(url, {
|
|
630
626
|
method,
|
|
@@ -645,14 +641,9 @@ var HttpClient = class {
|
|
|
645
641
|
);
|
|
646
642
|
continue;
|
|
647
643
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
}
|
|
651
|
-
return response;
|
|
644
|
+
detachOnExit = false;
|
|
645
|
+
return { response, releaseCallerSignal: removeCallerAbortListener };
|
|
652
646
|
} catch (err) {
|
|
653
|
-
if (timer !== void 0) {
|
|
654
|
-
clearTimeout(timer);
|
|
655
|
-
}
|
|
656
647
|
if (err?.name === "AbortError") {
|
|
657
648
|
if (controller?.signal.aborted && this.timeout > 0 && !callerSignal?.aborted) {
|
|
658
649
|
throw new ResultError(
|
|
@@ -672,6 +663,13 @@ var HttpClient = class {
|
|
|
672
663
|
0,
|
|
673
664
|
"NETWORK_ERROR"
|
|
674
665
|
);
|
|
666
|
+
} finally {
|
|
667
|
+
if (timer !== void 0) {
|
|
668
|
+
clearTimeout(timer);
|
|
669
|
+
}
|
|
670
|
+
if (detachOnExit) {
|
|
671
|
+
removeCallerAbortListener?.();
|
|
672
|
+
}
|
|
675
673
|
}
|
|
676
674
|
}
|
|
677
675
|
throw lastError || new ResultError(
|
|
@@ -734,7 +732,7 @@ var HttpClient = class {
|
|
|
734
732
|
});
|
|
735
733
|
}
|
|
736
734
|
this.logger.logRequest(method, url, requestHeaders, processedBody);
|
|
737
|
-
const response = await this.fetchWithRetry({
|
|
735
|
+
const { response, releaseCallerSignal } = await this.fetchWithRetry({
|
|
738
736
|
method,
|
|
739
737
|
url,
|
|
740
738
|
headers: requestHeaders,
|
|
@@ -757,6 +755,8 @@ var HttpClient = class {
|
|
|
757
755
|
);
|
|
758
756
|
}
|
|
759
757
|
throw err;
|
|
758
|
+
} finally {
|
|
759
|
+
releaseCallerSignal?.();
|
|
760
760
|
}
|
|
761
761
|
this.logger.logResponse(
|
|
762
762
|
method,
|
|
@@ -858,7 +858,7 @@ var HttpClient = class {
|
|
|
858
858
|
const callerSignal = initSignal ?? request?.signal;
|
|
859
859
|
const maxAttempts = IDEMPOTENT_METHODS.has(method.toUpperCase()) ? this.retryCount : 0;
|
|
860
860
|
this.logger.logRequest(method, url, requestHeaders, body);
|
|
861
|
-
const response = await this.fetchWithRetry({
|
|
861
|
+
const { response } = await this.fetchWithRetry({
|
|
862
862
|
method,
|
|
863
863
|
url,
|
|
864
864
|
headers: requestHeaders,
|
|
@@ -959,6 +959,10 @@ var HttpClient = class {
|
|
|
959
959
|
}
|
|
960
960
|
return headers;
|
|
961
961
|
}
|
|
962
|
+
/** Returns the publishable project key used to identify SDK usage reports. */
|
|
963
|
+
getAnonKey() {
|
|
964
|
+
return this.anonKey;
|
|
965
|
+
}
|
|
962
966
|
async refreshAccessToken() {
|
|
963
967
|
if (this.isRefreshing) {
|
|
964
968
|
return this.refreshPromise;
|
|
@@ -1028,6 +1032,47 @@ var HttpClient = class {
|
|
|
1028
1032
|
}
|
|
1029
1033
|
};
|
|
1030
1034
|
|
|
1035
|
+
// src/modules/ai-usage.ts
|
|
1036
|
+
var USAGE_ENDPOINT = "https://beta.result.dev/api/usage/ai";
|
|
1037
|
+
async function reportAiUsage(http, requestId, model, kind, tokens) {
|
|
1038
|
+
const anonKey = http.getAnonKey();
|
|
1039
|
+
if (!anonKey || !Number.isSafeInteger(tokens) || tokens <= 0) {
|
|
1040
|
+
return;
|
|
1041
|
+
}
|
|
1042
|
+
const controller = new AbortController();
|
|
1043
|
+
const timeout = setTimeout(() => controller.abort(), 2e3);
|
|
1044
|
+
try {
|
|
1045
|
+
const request = {
|
|
1046
|
+
method: "POST",
|
|
1047
|
+
headers: { "content-type": "application/json" },
|
|
1048
|
+
body: JSON.stringify({
|
|
1049
|
+
requestId,
|
|
1050
|
+
backendUrl: http.baseUrl,
|
|
1051
|
+
anonKey,
|
|
1052
|
+
model,
|
|
1053
|
+
kind,
|
|
1054
|
+
tokens
|
|
1055
|
+
}),
|
|
1056
|
+
keepalive: true,
|
|
1057
|
+
signal: controller.signal
|
|
1058
|
+
};
|
|
1059
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
1060
|
+
try {
|
|
1061
|
+
const response = await http.fetch(USAGE_ENDPOINT, request);
|
|
1062
|
+
if (response.status < 500) return;
|
|
1063
|
+
} catch {
|
|
1064
|
+
if (controller.signal.aborted) return;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
} catch {
|
|
1068
|
+
} finally {
|
|
1069
|
+
clearTimeout(timeout);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
function aiUsageRequestId() {
|
|
1073
|
+
return globalThis.crypto?.randomUUID?.() ?? null;
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1031
1076
|
// src/modules/ai.ts
|
|
1032
1077
|
var SUPPORTED_AUDIO_FORMATS = [
|
|
1033
1078
|
"wav",
|
|
@@ -1115,6 +1160,7 @@ var ChatCompletions = class {
|
|
|
1115
1160
|
}
|
|
1116
1161
|
http;
|
|
1117
1162
|
async create(params) {
|
|
1163
|
+
const usageRequestId = aiUsageRequestId();
|
|
1118
1164
|
const contentSummary = summarizeContent(params.messages ?? []);
|
|
1119
1165
|
assertSupportedContent(params.model, contentSummary);
|
|
1120
1166
|
const backendParams = {
|
|
@@ -1159,7 +1205,7 @@ var ChatCompletions = class {
|
|
|
1159
1205
|
contentSummary
|
|
1160
1206
|
);
|
|
1161
1207
|
}
|
|
1162
|
-
return this.parseSSEStream(response2, params.model);
|
|
1208
|
+
return this.parseSSEStream(response2, params.model, usageRequestId);
|
|
1163
1209
|
}
|
|
1164
1210
|
let response;
|
|
1165
1211
|
try {
|
|
@@ -1168,6 +1214,16 @@ var ChatCompletions = class {
|
|
|
1168
1214
|
throw enrichUpstreamError(error, contentSummary);
|
|
1169
1215
|
}
|
|
1170
1216
|
const content = response.text || "";
|
|
1217
|
+
const totalTokens = response.metadata?.usage?.totalTokens || 0;
|
|
1218
|
+
if (usageRequestId) {
|
|
1219
|
+
await reportAiUsage(
|
|
1220
|
+
this.http,
|
|
1221
|
+
usageRequestId,
|
|
1222
|
+
params.model,
|
|
1223
|
+
"chat",
|
|
1224
|
+
totalTokens
|
|
1225
|
+
);
|
|
1226
|
+
}
|
|
1171
1227
|
return {
|
|
1172
1228
|
id: `chatcmpl-${Date.now()}`,
|
|
1173
1229
|
object: "chat.completion",
|
|
@@ -1194,14 +1250,14 @@ var ChatCompletions = class {
|
|
|
1194
1250
|
usage: {
|
|
1195
1251
|
prompt_tokens: response.metadata?.usage?.promptTokens || 0,
|
|
1196
1252
|
completion_tokens: response.metadata?.usage?.completionTokens || 0,
|
|
1197
|
-
total_tokens:
|
|
1253
|
+
total_tokens: totalTokens
|
|
1198
1254
|
}
|
|
1199
1255
|
};
|
|
1200
1256
|
}
|
|
1201
1257
|
/**
|
|
1202
1258
|
* Parse SSE stream into async iterable of OpenAI-like chunks
|
|
1203
1259
|
*/
|
|
1204
|
-
async *parseSSEStream(response, model) {
|
|
1260
|
+
async *parseSSEStream(response, model, usageRequestId) {
|
|
1205
1261
|
const reader = response.body?.getReader();
|
|
1206
1262
|
if (!reader) {
|
|
1207
1263
|
throw new ResultError(
|
|
@@ -1279,6 +1335,15 @@ var ChatCompletions = class {
|
|
|
1279
1335
|
};
|
|
1280
1336
|
}
|
|
1281
1337
|
if (data.tokenUsage) {
|
|
1338
|
+
if (usageRequestId) {
|
|
1339
|
+
await reportAiUsage(
|
|
1340
|
+
this.http,
|
|
1341
|
+
usageRequestId,
|
|
1342
|
+
model,
|
|
1343
|
+
"chat",
|
|
1344
|
+
data.tokenUsage.totalTokens || 0
|
|
1345
|
+
);
|
|
1346
|
+
}
|
|
1282
1347
|
yield {
|
|
1283
1348
|
id: `chatcmpl-${Date.now()}`,
|
|
1284
1349
|
object: "chat.completion.chunk",
|
|
@@ -1350,17 +1415,28 @@ var Embeddings = class {
|
|
|
1350
1415
|
* ```
|
|
1351
1416
|
*/
|
|
1352
1417
|
async create(params) {
|
|
1418
|
+
const usageRequestId = aiUsageRequestId();
|
|
1353
1419
|
const response = await this.http.post(
|
|
1354
1420
|
"/api/ai/embeddings",
|
|
1355
1421
|
params
|
|
1356
1422
|
);
|
|
1423
|
+
const totalTokens = response.metadata?.usage?.totalTokens || 0;
|
|
1424
|
+
if (usageRequestId) {
|
|
1425
|
+
await reportAiUsage(
|
|
1426
|
+
this.http,
|
|
1427
|
+
usageRequestId,
|
|
1428
|
+
params.model,
|
|
1429
|
+
"embeddings",
|
|
1430
|
+
totalTokens
|
|
1431
|
+
);
|
|
1432
|
+
}
|
|
1357
1433
|
return {
|
|
1358
1434
|
object: response.object,
|
|
1359
1435
|
data: response.data,
|
|
1360
1436
|
model: response.metadata?.model,
|
|
1361
1437
|
usage: response.metadata?.usage ? {
|
|
1362
1438
|
prompt_tokens: response.metadata.usage.promptTokens || 0,
|
|
1363
|
-
total_tokens:
|
|
1439
|
+
total_tokens: totalTokens
|
|
1364
1440
|
} : {
|
|
1365
1441
|
prompt_tokens: 0,
|
|
1366
1442
|
total_tokens: 0
|
|
@@ -1398,6 +1474,7 @@ var Images = class {
|
|
|
1398
1474
|
* ```
|
|
1399
1475
|
*/
|
|
1400
1476
|
async generate(params) {
|
|
1477
|
+
const usageRequestId = aiUsageRequestId();
|
|
1401
1478
|
const response = await this.http.post(
|
|
1402
1479
|
"/api/ai/image/generation",
|
|
1403
1480
|
params
|
|
@@ -1411,6 +1488,16 @@ var Images = class {
|
|
|
1411
1488
|
} else if (response.text) {
|
|
1412
1489
|
data = [{ content: response.text }];
|
|
1413
1490
|
}
|
|
1491
|
+
const totalTokens = response.metadata?.usage?.totalTokens || 0;
|
|
1492
|
+
if (usageRequestId) {
|
|
1493
|
+
await reportAiUsage(
|
|
1494
|
+
this.http,
|
|
1495
|
+
usageRequestId,
|
|
1496
|
+
params.model,
|
|
1497
|
+
"image",
|
|
1498
|
+
totalTokens
|
|
1499
|
+
);
|
|
1500
|
+
}
|
|
1414
1501
|
return {
|
|
1415
1502
|
created: Math.floor(Date.now() / 1e3),
|
|
1416
1503
|
data,
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { R as ResultClient } from './client-
|
|
2
|
-
export { A as AI, a as AccessTokenChangeEvent, b as Auth, c as AuthChangeEvent, d as AuthStateChangeCallback, C as ChatCompletion, e as ChatCompletionChoice, f as ChatCompletionChunk, g as ChatCompletionUsage, h as ConnectionState, D as Database, E as Emails, i as EmbeddingsResult, j as EventCallback, F as FunctionInvokeOptions, k as Functions, H as HttpClient, I as ImageGenerationResult, L as Logger, l as Realtime, S as Storage, m as StorageBucket, n as StorageResponse } from './client-
|
|
3
|
-
import { R as ResultAdminConfig, a as ResultConfig } from './types-
|
|
4
|
-
export { A as Analytics, b as AnalyticsOptions, c as ApiError, d as AuthErrorResponse, e as AuthSession, C as ChatCompletionRequest, f as ChatMessageSchema, g as CreateSessionRequest, h as CreateUserRequest, D as DeleteObjectResult, i as DeleteObjectsResponse, E as ERROR_CODES, j as EmbeddingsRequest, k as ErrorCode, I as ImageGenerationRequest, O as OAUTH_PROVIDERS, l as OAuthProvidersSchema, P as PresenceMember, m as ProfileSchema, n as RealtimeErrorPayload, o as ResultError, p as ResultErrorCode, S as SendEmailOptions, q as SendEmailResponse, r as SocketMessage, s as StartThreadOptions, t as StartedThread, u as StorageFileSchema, v as SubscribeResponse, w as Support, x as SupportMessage, y as SupportOptions, z as SupportThread, T as Tool, B as ToolCall, F as ToolChoice, U as UserSchema } from './types-
|
|
1
|
+
import { R as ResultClient } from './client-N6MW9IE1.cjs';
|
|
2
|
+
export { A as AI, a as AccessTokenChangeEvent, b as Auth, c as AuthChangeEvent, d as AuthStateChangeCallback, C as ChatCompletion, e as ChatCompletionChoice, f as ChatCompletionChunk, g as ChatCompletionUsage, h as ConnectionState, D as Database, E as Emails, i as EmbeddingsResult, j as EventCallback, F as FunctionInvokeOptions, k as Functions, H as HttpClient, I as ImageGenerationResult, L as Logger, l as Realtime, S as Storage, m as StorageBucket, n as StorageResponse } from './client-N6MW9IE1.cjs';
|
|
3
|
+
import { R as ResultAdminConfig, a as ResultConfig } from './types-BTdjI7Yj.cjs';
|
|
4
|
+
export { A as Analytics, b as AnalyticsOptions, c as ApiError, d as AuthErrorResponse, e as AuthSession, C as ChatCompletionRequest, f as ChatMessageSchema, g as CreateSessionRequest, h as CreateUserRequest, D as DeleteObjectResult, i as DeleteObjectsResponse, E as ERROR_CODES, j as EmbeddingsRequest, k as ErrorCode, I as ImageGenerationRequest, O as OAUTH_PROVIDERS, l as OAuthProvidersSchema, P as PresenceMember, m as ProfileSchema, n as RealtimeErrorPayload, o as ResultError, p as ResultErrorCode, S as SendEmailOptions, q as SendEmailResponse, r as SocketMessage, s as StartThreadOptions, t as StartedThread, u as StorageFileSchema, v as SubscribeResponse, w as Support, x as SupportMessage, y as SupportOptions, z as SupportThread, T as Tool, B as ToolCall, F as ToolChoice, U as UserSchema } from './types-BTdjI7Yj.cjs';
|
|
5
5
|
import '@supabase/postgrest-js';
|
|
6
6
|
|
|
7
7
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { R as ResultClient } from './client
|
|
2
|
-
export { A as AI, a as AccessTokenChangeEvent, b as Auth, c as AuthChangeEvent, d as AuthStateChangeCallback, C as ChatCompletion, e as ChatCompletionChoice, f as ChatCompletionChunk, g as ChatCompletionUsage, h as ConnectionState, D as Database, E as Emails, i as EmbeddingsResult, j as EventCallback, F as FunctionInvokeOptions, k as Functions, H as HttpClient, I as ImageGenerationResult, L as Logger, l as Realtime, S as Storage, m as StorageBucket, n as StorageResponse } from './client
|
|
3
|
-
import { R as ResultAdminConfig, a as ResultConfig } from './types-
|
|
4
|
-
export { A as Analytics, b as AnalyticsOptions, c as ApiError, d as AuthErrorResponse, e as AuthSession, C as ChatCompletionRequest, f as ChatMessageSchema, g as CreateSessionRequest, h as CreateUserRequest, D as DeleteObjectResult, i as DeleteObjectsResponse, E as ERROR_CODES, j as EmbeddingsRequest, k as ErrorCode, I as ImageGenerationRequest, O as OAUTH_PROVIDERS, l as OAuthProvidersSchema, P as PresenceMember, m as ProfileSchema, n as RealtimeErrorPayload, o as ResultError, p as ResultErrorCode, S as SendEmailOptions, q as SendEmailResponse, r as SocketMessage, s as StartThreadOptions, t as StartedThread, u as StorageFileSchema, v as SubscribeResponse, w as Support, x as SupportMessage, y as SupportOptions, z as SupportThread, T as Tool, B as ToolCall, F as ToolChoice, U as UserSchema } from './types-
|
|
1
|
+
import { R as ResultClient } from './client-D5IGLPW4.js';
|
|
2
|
+
export { A as AI, a as AccessTokenChangeEvent, b as Auth, c as AuthChangeEvent, d as AuthStateChangeCallback, C as ChatCompletion, e as ChatCompletionChoice, f as ChatCompletionChunk, g as ChatCompletionUsage, h as ConnectionState, D as Database, E as Emails, i as EmbeddingsResult, j as EventCallback, F as FunctionInvokeOptions, k as Functions, H as HttpClient, I as ImageGenerationResult, L as Logger, l as Realtime, S as Storage, m as StorageBucket, n as StorageResponse } from './client-D5IGLPW4.js';
|
|
3
|
+
import { R as ResultAdminConfig, a as ResultConfig } from './types-BTdjI7Yj.js';
|
|
4
|
+
export { A as Analytics, b as AnalyticsOptions, c as ApiError, d as AuthErrorResponse, e as AuthSession, C as ChatCompletionRequest, f as ChatMessageSchema, g as CreateSessionRequest, h as CreateUserRequest, D as DeleteObjectResult, i as DeleteObjectsResponse, E as ERROR_CODES, j as EmbeddingsRequest, k as ErrorCode, I as ImageGenerationRequest, O as OAUTH_PROVIDERS, l as OAuthProvidersSchema, P as PresenceMember, m as ProfileSchema, n as RealtimeErrorPayload, o as ResultError, p as ResultErrorCode, S as SendEmailOptions, q as SendEmailResponse, r as SocketMessage, s as StartThreadOptions, t as StartedThread, u as StorageFileSchema, v as SubscribeResponse, w as Support, x as SupportMessage, y as SupportOptions, z as SupportThread, T as Tool, B as ToolCall, F as ToolChoice, U as UserSchema } from './types-BTdjI7Yj.js';
|
|
5
5
|
import '@supabase/postgrest-js';
|
|
6
6
|
|
|
7
7
|
/**
|
package/dist/index.js
CHANGED
|
@@ -547,6 +547,7 @@ var HttpClient = class {
|
|
|
547
547
|
}
|
|
548
548
|
let controller;
|
|
549
549
|
let timer;
|
|
550
|
+
let removeCallerAbortListener;
|
|
550
551
|
if (this.timeout > 0 || callerSignal) {
|
|
551
552
|
controller = new AbortController();
|
|
552
553
|
if (this.timeout > 0) {
|
|
@@ -560,16 +561,11 @@ var HttpClient = class {
|
|
|
560
561
|
callerSignal.addEventListener("abort", onCallerAbort, {
|
|
561
562
|
once: true
|
|
562
563
|
});
|
|
563
|
-
|
|
564
|
-
"abort",
|
|
565
|
-
() => {
|
|
566
|
-
callerSignal.removeEventListener("abort", onCallerAbort);
|
|
567
|
-
},
|
|
568
|
-
{ once: true }
|
|
569
|
-
);
|
|
564
|
+
removeCallerAbortListener = () => callerSignal.removeEventListener("abort", onCallerAbort);
|
|
570
565
|
}
|
|
571
566
|
}
|
|
572
567
|
}
|
|
568
|
+
let detachOnExit = true;
|
|
573
569
|
try {
|
|
574
570
|
const response = await this.fetch(url, {
|
|
575
571
|
method,
|
|
@@ -590,14 +586,9 @@ var HttpClient = class {
|
|
|
590
586
|
);
|
|
591
587
|
continue;
|
|
592
588
|
}
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
}
|
|
596
|
-
return response;
|
|
589
|
+
detachOnExit = false;
|
|
590
|
+
return { response, releaseCallerSignal: removeCallerAbortListener };
|
|
597
591
|
} catch (err) {
|
|
598
|
-
if (timer !== void 0) {
|
|
599
|
-
clearTimeout(timer);
|
|
600
|
-
}
|
|
601
592
|
if (err?.name === "AbortError") {
|
|
602
593
|
if (controller?.signal.aborted && this.timeout > 0 && !callerSignal?.aborted) {
|
|
603
594
|
throw new ResultError(
|
|
@@ -617,6 +608,13 @@ var HttpClient = class {
|
|
|
617
608
|
0,
|
|
618
609
|
"NETWORK_ERROR"
|
|
619
610
|
);
|
|
611
|
+
} finally {
|
|
612
|
+
if (timer !== void 0) {
|
|
613
|
+
clearTimeout(timer);
|
|
614
|
+
}
|
|
615
|
+
if (detachOnExit) {
|
|
616
|
+
removeCallerAbortListener?.();
|
|
617
|
+
}
|
|
620
618
|
}
|
|
621
619
|
}
|
|
622
620
|
throw lastError || new ResultError(
|
|
@@ -679,7 +677,7 @@ var HttpClient = class {
|
|
|
679
677
|
});
|
|
680
678
|
}
|
|
681
679
|
this.logger.logRequest(method, url, requestHeaders, processedBody);
|
|
682
|
-
const response = await this.fetchWithRetry({
|
|
680
|
+
const { response, releaseCallerSignal } = await this.fetchWithRetry({
|
|
683
681
|
method,
|
|
684
682
|
url,
|
|
685
683
|
headers: requestHeaders,
|
|
@@ -702,6 +700,8 @@ var HttpClient = class {
|
|
|
702
700
|
);
|
|
703
701
|
}
|
|
704
702
|
throw err;
|
|
703
|
+
} finally {
|
|
704
|
+
releaseCallerSignal?.();
|
|
705
705
|
}
|
|
706
706
|
this.logger.logResponse(
|
|
707
707
|
method,
|
|
@@ -803,7 +803,7 @@ var HttpClient = class {
|
|
|
803
803
|
const callerSignal = initSignal ?? request?.signal;
|
|
804
804
|
const maxAttempts = IDEMPOTENT_METHODS.has(method.toUpperCase()) ? this.retryCount : 0;
|
|
805
805
|
this.logger.logRequest(method, url, requestHeaders, body);
|
|
806
|
-
const response = await this.fetchWithRetry({
|
|
806
|
+
const { response } = await this.fetchWithRetry({
|
|
807
807
|
method,
|
|
808
808
|
url,
|
|
809
809
|
headers: requestHeaders,
|
|
@@ -904,6 +904,10 @@ var HttpClient = class {
|
|
|
904
904
|
}
|
|
905
905
|
return headers;
|
|
906
906
|
}
|
|
907
|
+
/** Returns the publishable project key used to identify SDK usage reports. */
|
|
908
|
+
getAnonKey() {
|
|
909
|
+
return this.anonKey;
|
|
910
|
+
}
|
|
907
911
|
async refreshAccessToken() {
|
|
908
912
|
if (this.isRefreshing) {
|
|
909
913
|
return this.refreshPromise;
|
|
@@ -973,6 +977,47 @@ var HttpClient = class {
|
|
|
973
977
|
}
|
|
974
978
|
};
|
|
975
979
|
|
|
980
|
+
// src/modules/ai-usage.ts
|
|
981
|
+
var USAGE_ENDPOINT = "https://beta.result.dev/api/usage/ai";
|
|
982
|
+
async function reportAiUsage(http, requestId, model, kind, tokens) {
|
|
983
|
+
const anonKey = http.getAnonKey();
|
|
984
|
+
if (!anonKey || !Number.isSafeInteger(tokens) || tokens <= 0) {
|
|
985
|
+
return;
|
|
986
|
+
}
|
|
987
|
+
const controller = new AbortController();
|
|
988
|
+
const timeout = setTimeout(() => controller.abort(), 2e3);
|
|
989
|
+
try {
|
|
990
|
+
const request = {
|
|
991
|
+
method: "POST",
|
|
992
|
+
headers: { "content-type": "application/json" },
|
|
993
|
+
body: JSON.stringify({
|
|
994
|
+
requestId,
|
|
995
|
+
backendUrl: http.baseUrl,
|
|
996
|
+
anonKey,
|
|
997
|
+
model,
|
|
998
|
+
kind,
|
|
999
|
+
tokens
|
|
1000
|
+
}),
|
|
1001
|
+
keepalive: true,
|
|
1002
|
+
signal: controller.signal
|
|
1003
|
+
};
|
|
1004
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
1005
|
+
try {
|
|
1006
|
+
const response = await http.fetch(USAGE_ENDPOINT, request);
|
|
1007
|
+
if (response.status < 500) return;
|
|
1008
|
+
} catch {
|
|
1009
|
+
if (controller.signal.aborted) return;
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
} catch {
|
|
1013
|
+
} finally {
|
|
1014
|
+
clearTimeout(timeout);
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
function aiUsageRequestId() {
|
|
1018
|
+
return globalThis.crypto?.randomUUID?.() ?? null;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
976
1021
|
// src/modules/ai.ts
|
|
977
1022
|
var SUPPORTED_AUDIO_FORMATS = [
|
|
978
1023
|
"wav",
|
|
@@ -1060,6 +1105,7 @@ var ChatCompletions = class {
|
|
|
1060
1105
|
}
|
|
1061
1106
|
http;
|
|
1062
1107
|
async create(params) {
|
|
1108
|
+
const usageRequestId = aiUsageRequestId();
|
|
1063
1109
|
const contentSummary = summarizeContent(params.messages ?? []);
|
|
1064
1110
|
assertSupportedContent(params.model, contentSummary);
|
|
1065
1111
|
const backendParams = {
|
|
@@ -1104,7 +1150,7 @@ var ChatCompletions = class {
|
|
|
1104
1150
|
contentSummary
|
|
1105
1151
|
);
|
|
1106
1152
|
}
|
|
1107
|
-
return this.parseSSEStream(response2, params.model);
|
|
1153
|
+
return this.parseSSEStream(response2, params.model, usageRequestId);
|
|
1108
1154
|
}
|
|
1109
1155
|
let response;
|
|
1110
1156
|
try {
|
|
@@ -1113,6 +1159,16 @@ var ChatCompletions = class {
|
|
|
1113
1159
|
throw enrichUpstreamError(error, contentSummary);
|
|
1114
1160
|
}
|
|
1115
1161
|
const content = response.text || "";
|
|
1162
|
+
const totalTokens = response.metadata?.usage?.totalTokens || 0;
|
|
1163
|
+
if (usageRequestId) {
|
|
1164
|
+
await reportAiUsage(
|
|
1165
|
+
this.http,
|
|
1166
|
+
usageRequestId,
|
|
1167
|
+
params.model,
|
|
1168
|
+
"chat",
|
|
1169
|
+
totalTokens
|
|
1170
|
+
);
|
|
1171
|
+
}
|
|
1116
1172
|
return {
|
|
1117
1173
|
id: `chatcmpl-${Date.now()}`,
|
|
1118
1174
|
object: "chat.completion",
|
|
@@ -1139,14 +1195,14 @@ var ChatCompletions = class {
|
|
|
1139
1195
|
usage: {
|
|
1140
1196
|
prompt_tokens: response.metadata?.usage?.promptTokens || 0,
|
|
1141
1197
|
completion_tokens: response.metadata?.usage?.completionTokens || 0,
|
|
1142
|
-
total_tokens:
|
|
1198
|
+
total_tokens: totalTokens
|
|
1143
1199
|
}
|
|
1144
1200
|
};
|
|
1145
1201
|
}
|
|
1146
1202
|
/**
|
|
1147
1203
|
* Parse SSE stream into async iterable of OpenAI-like chunks
|
|
1148
1204
|
*/
|
|
1149
|
-
async *parseSSEStream(response, model) {
|
|
1205
|
+
async *parseSSEStream(response, model, usageRequestId) {
|
|
1150
1206
|
const reader = response.body?.getReader();
|
|
1151
1207
|
if (!reader) {
|
|
1152
1208
|
throw new ResultError(
|
|
@@ -1224,6 +1280,15 @@ var ChatCompletions = class {
|
|
|
1224
1280
|
};
|
|
1225
1281
|
}
|
|
1226
1282
|
if (data.tokenUsage) {
|
|
1283
|
+
if (usageRequestId) {
|
|
1284
|
+
await reportAiUsage(
|
|
1285
|
+
this.http,
|
|
1286
|
+
usageRequestId,
|
|
1287
|
+
model,
|
|
1288
|
+
"chat",
|
|
1289
|
+
data.tokenUsage.totalTokens || 0
|
|
1290
|
+
);
|
|
1291
|
+
}
|
|
1227
1292
|
yield {
|
|
1228
1293
|
id: `chatcmpl-${Date.now()}`,
|
|
1229
1294
|
object: "chat.completion.chunk",
|
|
@@ -1295,17 +1360,28 @@ var Embeddings = class {
|
|
|
1295
1360
|
* ```
|
|
1296
1361
|
*/
|
|
1297
1362
|
async create(params) {
|
|
1363
|
+
const usageRequestId = aiUsageRequestId();
|
|
1298
1364
|
const response = await this.http.post(
|
|
1299
1365
|
"/api/ai/embeddings",
|
|
1300
1366
|
params
|
|
1301
1367
|
);
|
|
1368
|
+
const totalTokens = response.metadata?.usage?.totalTokens || 0;
|
|
1369
|
+
if (usageRequestId) {
|
|
1370
|
+
await reportAiUsage(
|
|
1371
|
+
this.http,
|
|
1372
|
+
usageRequestId,
|
|
1373
|
+
params.model,
|
|
1374
|
+
"embeddings",
|
|
1375
|
+
totalTokens
|
|
1376
|
+
);
|
|
1377
|
+
}
|
|
1302
1378
|
return {
|
|
1303
1379
|
object: response.object,
|
|
1304
1380
|
data: response.data,
|
|
1305
1381
|
model: response.metadata?.model,
|
|
1306
1382
|
usage: response.metadata?.usage ? {
|
|
1307
1383
|
prompt_tokens: response.metadata.usage.promptTokens || 0,
|
|
1308
|
-
total_tokens:
|
|
1384
|
+
total_tokens: totalTokens
|
|
1309
1385
|
} : {
|
|
1310
1386
|
prompt_tokens: 0,
|
|
1311
1387
|
total_tokens: 0
|
|
@@ -1343,6 +1419,7 @@ var Images = class {
|
|
|
1343
1419
|
* ```
|
|
1344
1420
|
*/
|
|
1345
1421
|
async generate(params) {
|
|
1422
|
+
const usageRequestId = aiUsageRequestId();
|
|
1346
1423
|
const response = await this.http.post(
|
|
1347
1424
|
"/api/ai/image/generation",
|
|
1348
1425
|
params
|
|
@@ -1356,6 +1433,16 @@ var Images = class {
|
|
|
1356
1433
|
} else if (response.text) {
|
|
1357
1434
|
data = [{ content: response.text }];
|
|
1358
1435
|
}
|
|
1436
|
+
const totalTokens = response.metadata?.usage?.totalTokens || 0;
|
|
1437
|
+
if (usageRequestId) {
|
|
1438
|
+
await reportAiUsage(
|
|
1439
|
+
this.http,
|
|
1440
|
+
usageRequestId,
|
|
1441
|
+
params.model,
|
|
1442
|
+
"image",
|
|
1443
|
+
totalTokens
|
|
1444
|
+
);
|
|
1445
|
+
}
|
|
1359
1446
|
return {
|
|
1360
1447
|
created: Math.floor(Date.now() / 1e3),
|
|
1361
1448
|
data,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ResultConfig, o as ResultError } from './types-
|
|
1
|
+
import { a as ResultConfig, o as ResultError } from './types-BTdjI7Yj.js';
|
|
2
2
|
|
|
3
3
|
declare const DEFAULT_ACCESS_TOKEN_COOKIE = "result_access_token";
|
|
4
4
|
declare const DEFAULT_REFRESH_TOKEN_COOKIE = "result_refresh_token";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ResultConfig, o as ResultError } from './types-
|
|
1
|
+
import { a as ResultConfig, o as ResultError } from './types-BTdjI7Yj.cjs';
|
|
2
2
|
|
|
3
3
|
declare const DEFAULT_ACCESS_TOKEN_COOKIE = "result_access_token";
|
|
4
4
|
declare const DEFAULT_REFRESH_TOKEN_COOKIE = "result_refresh_token";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { b as AuthCookieNames, c as AuthCookieOptions, A as AuthCookieSettings, d as CookieOptions, e as CookieReader, C as CookieStore, a as CookieWriter, D as DEFAULT_ACCESS_TOKEN_COOKIE, f as DEFAULT_REFRESH_TOKEN_COOKIE, U as UpdateSessionOptions, g as UpdateSessionResult, i as clearAuthCookies, j as getAccessTokenCookieName, k as getRefreshTokenCookieName, s as setAuthCookies, u as updateSession } from '../middleware-
|
|
2
|
-
import '../types-
|
|
1
|
+
export { b as AuthCookieNames, c as AuthCookieOptions, A as AuthCookieSettings, d as CookieOptions, e as CookieReader, C as CookieStore, a as CookieWriter, D as DEFAULT_ACCESS_TOKEN_COOKIE, f as DEFAULT_REFRESH_TOKEN_COOKIE, U as UpdateSessionOptions, g as UpdateSessionResult, i as clearAuthCookies, j as getAccessTokenCookieName, k as getRefreshTokenCookieName, s as setAuthCookies, u as updateSession } from '../middleware-CGn44ocX.cjs';
|
|
2
|
+
import '../types-BTdjI7Yj.cjs';
|
package/dist/ssr/middleware.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { b as AuthCookieNames, c as AuthCookieOptions, A as AuthCookieSettings, d as CookieOptions, e as CookieReader, C as CookieStore, a as CookieWriter, D as DEFAULT_ACCESS_TOKEN_COOKIE, f as DEFAULT_REFRESH_TOKEN_COOKIE, U as UpdateSessionOptions, g as UpdateSessionResult, i as clearAuthCookies, j as getAccessTokenCookieName, k as getRefreshTokenCookieName, s as setAuthCookies, u as updateSession } from '../middleware-
|
|
2
|
-
import '../types-
|
|
1
|
+
export { b as AuthCookieNames, c as AuthCookieOptions, A as AuthCookieSettings, d as CookieOptions, e as CookieReader, C as CookieStore, a as CookieWriter, D as DEFAULT_ACCESS_TOKEN_COOKIE, f as DEFAULT_REFRESH_TOKEN_COOKIE, U as UpdateSessionOptions, g as UpdateSessionResult, i as clearAuthCookies, j as getAccessTokenCookieName, k as getRefreshTokenCookieName, s as setAuthCookies, u as updateSession } from '../middleware-8UNqItQG.js';
|
|
2
|
+
import '../types-BTdjI7Yj.js';
|
package/dist/ssr.cjs
CHANGED
|
@@ -789,6 +789,7 @@ var HttpClient = class {
|
|
|
789
789
|
}
|
|
790
790
|
let controller;
|
|
791
791
|
let timer;
|
|
792
|
+
let removeCallerAbortListener;
|
|
792
793
|
if (this.timeout > 0 || callerSignal) {
|
|
793
794
|
controller = new AbortController();
|
|
794
795
|
if (this.timeout > 0) {
|
|
@@ -802,16 +803,11 @@ var HttpClient = class {
|
|
|
802
803
|
callerSignal.addEventListener("abort", onCallerAbort, {
|
|
803
804
|
once: true
|
|
804
805
|
});
|
|
805
|
-
|
|
806
|
-
"abort",
|
|
807
|
-
() => {
|
|
808
|
-
callerSignal.removeEventListener("abort", onCallerAbort);
|
|
809
|
-
},
|
|
810
|
-
{ once: true }
|
|
811
|
-
);
|
|
806
|
+
removeCallerAbortListener = () => callerSignal.removeEventListener("abort", onCallerAbort);
|
|
812
807
|
}
|
|
813
808
|
}
|
|
814
809
|
}
|
|
810
|
+
let detachOnExit = true;
|
|
815
811
|
try {
|
|
816
812
|
const response = await this.fetch(url, {
|
|
817
813
|
method,
|
|
@@ -832,14 +828,9 @@ var HttpClient = class {
|
|
|
832
828
|
);
|
|
833
829
|
continue;
|
|
834
830
|
}
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
}
|
|
838
|
-
return response;
|
|
831
|
+
detachOnExit = false;
|
|
832
|
+
return { response, releaseCallerSignal: removeCallerAbortListener };
|
|
839
833
|
} catch (err) {
|
|
840
|
-
if (timer !== void 0) {
|
|
841
|
-
clearTimeout(timer);
|
|
842
|
-
}
|
|
843
834
|
if (err?.name === "AbortError") {
|
|
844
835
|
if (controller?.signal.aborted && this.timeout > 0 && !callerSignal?.aborted) {
|
|
845
836
|
throw new ResultError(
|
|
@@ -859,6 +850,13 @@ var HttpClient = class {
|
|
|
859
850
|
0,
|
|
860
851
|
"NETWORK_ERROR"
|
|
861
852
|
);
|
|
853
|
+
} finally {
|
|
854
|
+
if (timer !== void 0) {
|
|
855
|
+
clearTimeout(timer);
|
|
856
|
+
}
|
|
857
|
+
if (detachOnExit) {
|
|
858
|
+
removeCallerAbortListener?.();
|
|
859
|
+
}
|
|
862
860
|
}
|
|
863
861
|
}
|
|
864
862
|
throw lastError || new ResultError(
|
|
@@ -921,7 +919,7 @@ var HttpClient = class {
|
|
|
921
919
|
});
|
|
922
920
|
}
|
|
923
921
|
this.logger.logRequest(method, url, requestHeaders, processedBody);
|
|
924
|
-
const response = await this.fetchWithRetry({
|
|
922
|
+
const { response, releaseCallerSignal } = await this.fetchWithRetry({
|
|
925
923
|
method,
|
|
926
924
|
url,
|
|
927
925
|
headers: requestHeaders,
|
|
@@ -944,6 +942,8 @@ var HttpClient = class {
|
|
|
944
942
|
);
|
|
945
943
|
}
|
|
946
944
|
throw err;
|
|
945
|
+
} finally {
|
|
946
|
+
releaseCallerSignal?.();
|
|
947
947
|
}
|
|
948
948
|
this.logger.logResponse(
|
|
949
949
|
method,
|
|
@@ -1045,7 +1045,7 @@ var HttpClient = class {
|
|
|
1045
1045
|
const callerSignal = initSignal ?? request?.signal;
|
|
1046
1046
|
const maxAttempts = IDEMPOTENT_METHODS.has(method.toUpperCase()) ? this.retryCount : 0;
|
|
1047
1047
|
this.logger.logRequest(method, url, requestHeaders, body);
|
|
1048
|
-
const response = await this.fetchWithRetry({
|
|
1048
|
+
const { response } = await this.fetchWithRetry({
|
|
1049
1049
|
method,
|
|
1050
1050
|
url,
|
|
1051
1051
|
headers: requestHeaders,
|
|
@@ -1146,6 +1146,10 @@ var HttpClient = class {
|
|
|
1146
1146
|
}
|
|
1147
1147
|
return headers;
|
|
1148
1148
|
}
|
|
1149
|
+
/** Returns the publishable project key used to identify SDK usage reports. */
|
|
1150
|
+
getAnonKey() {
|
|
1151
|
+
return this.anonKey;
|
|
1152
|
+
}
|
|
1149
1153
|
async refreshAccessToken() {
|
|
1150
1154
|
if (this.isRefreshing) {
|
|
1151
1155
|
return this.refreshPromise;
|
|
@@ -1215,6 +1219,47 @@ var HttpClient = class {
|
|
|
1215
1219
|
}
|
|
1216
1220
|
};
|
|
1217
1221
|
|
|
1222
|
+
// src/modules/ai-usage.ts
|
|
1223
|
+
var USAGE_ENDPOINT = "https://beta.result.dev/api/usage/ai";
|
|
1224
|
+
async function reportAiUsage(http, requestId, model, kind, tokens) {
|
|
1225
|
+
const anonKey = http.getAnonKey();
|
|
1226
|
+
if (!anonKey || !Number.isSafeInteger(tokens) || tokens <= 0) {
|
|
1227
|
+
return;
|
|
1228
|
+
}
|
|
1229
|
+
const controller = new AbortController();
|
|
1230
|
+
const timeout = setTimeout(() => controller.abort(), 2e3);
|
|
1231
|
+
try {
|
|
1232
|
+
const request = {
|
|
1233
|
+
method: "POST",
|
|
1234
|
+
headers: { "content-type": "application/json" },
|
|
1235
|
+
body: JSON.stringify({
|
|
1236
|
+
requestId,
|
|
1237
|
+
backendUrl: http.baseUrl,
|
|
1238
|
+
anonKey,
|
|
1239
|
+
model,
|
|
1240
|
+
kind,
|
|
1241
|
+
tokens
|
|
1242
|
+
}),
|
|
1243
|
+
keepalive: true,
|
|
1244
|
+
signal: controller.signal
|
|
1245
|
+
};
|
|
1246
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
1247
|
+
try {
|
|
1248
|
+
const response = await http.fetch(USAGE_ENDPOINT, request);
|
|
1249
|
+
if (response.status < 500) return;
|
|
1250
|
+
} catch {
|
|
1251
|
+
if (controller.signal.aborted) return;
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
} catch {
|
|
1255
|
+
} finally {
|
|
1256
|
+
clearTimeout(timeout);
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
function aiUsageRequestId() {
|
|
1260
|
+
return globalThis.crypto?.randomUUID?.() ?? null;
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1218
1263
|
// src/modules/ai.ts
|
|
1219
1264
|
var SUPPORTED_AUDIO_FORMATS = [
|
|
1220
1265
|
"wav",
|
|
@@ -1302,6 +1347,7 @@ var ChatCompletions = class {
|
|
|
1302
1347
|
}
|
|
1303
1348
|
http;
|
|
1304
1349
|
async create(params) {
|
|
1350
|
+
const usageRequestId = aiUsageRequestId();
|
|
1305
1351
|
const contentSummary = summarizeContent(params.messages ?? []);
|
|
1306
1352
|
assertSupportedContent(params.model, contentSummary);
|
|
1307
1353
|
const backendParams = {
|
|
@@ -1346,7 +1392,7 @@ var ChatCompletions = class {
|
|
|
1346
1392
|
contentSummary
|
|
1347
1393
|
);
|
|
1348
1394
|
}
|
|
1349
|
-
return this.parseSSEStream(response2, params.model);
|
|
1395
|
+
return this.parseSSEStream(response2, params.model, usageRequestId);
|
|
1350
1396
|
}
|
|
1351
1397
|
let response;
|
|
1352
1398
|
try {
|
|
@@ -1355,6 +1401,16 @@ var ChatCompletions = class {
|
|
|
1355
1401
|
throw enrichUpstreamError(error, contentSummary);
|
|
1356
1402
|
}
|
|
1357
1403
|
const content = response.text || "";
|
|
1404
|
+
const totalTokens = response.metadata?.usage?.totalTokens || 0;
|
|
1405
|
+
if (usageRequestId) {
|
|
1406
|
+
await reportAiUsage(
|
|
1407
|
+
this.http,
|
|
1408
|
+
usageRequestId,
|
|
1409
|
+
params.model,
|
|
1410
|
+
"chat",
|
|
1411
|
+
totalTokens
|
|
1412
|
+
);
|
|
1413
|
+
}
|
|
1358
1414
|
return {
|
|
1359
1415
|
id: `chatcmpl-${Date.now()}`,
|
|
1360
1416
|
object: "chat.completion",
|
|
@@ -1381,14 +1437,14 @@ var ChatCompletions = class {
|
|
|
1381
1437
|
usage: {
|
|
1382
1438
|
prompt_tokens: response.metadata?.usage?.promptTokens || 0,
|
|
1383
1439
|
completion_tokens: response.metadata?.usage?.completionTokens || 0,
|
|
1384
|
-
total_tokens:
|
|
1440
|
+
total_tokens: totalTokens
|
|
1385
1441
|
}
|
|
1386
1442
|
};
|
|
1387
1443
|
}
|
|
1388
1444
|
/**
|
|
1389
1445
|
* Parse SSE stream into async iterable of OpenAI-like chunks
|
|
1390
1446
|
*/
|
|
1391
|
-
async *parseSSEStream(response, model) {
|
|
1447
|
+
async *parseSSEStream(response, model, usageRequestId) {
|
|
1392
1448
|
const reader = response.body?.getReader();
|
|
1393
1449
|
if (!reader) {
|
|
1394
1450
|
throw new ResultError(
|
|
@@ -1466,6 +1522,15 @@ var ChatCompletions = class {
|
|
|
1466
1522
|
};
|
|
1467
1523
|
}
|
|
1468
1524
|
if (data.tokenUsage) {
|
|
1525
|
+
if (usageRequestId) {
|
|
1526
|
+
await reportAiUsage(
|
|
1527
|
+
this.http,
|
|
1528
|
+
usageRequestId,
|
|
1529
|
+
model,
|
|
1530
|
+
"chat",
|
|
1531
|
+
data.tokenUsage.totalTokens || 0
|
|
1532
|
+
);
|
|
1533
|
+
}
|
|
1469
1534
|
yield {
|
|
1470
1535
|
id: `chatcmpl-${Date.now()}`,
|
|
1471
1536
|
object: "chat.completion.chunk",
|
|
@@ -1537,17 +1602,28 @@ var Embeddings = class {
|
|
|
1537
1602
|
* ```
|
|
1538
1603
|
*/
|
|
1539
1604
|
async create(params) {
|
|
1605
|
+
const usageRequestId = aiUsageRequestId();
|
|
1540
1606
|
const response = await this.http.post(
|
|
1541
1607
|
"/api/ai/embeddings",
|
|
1542
1608
|
params
|
|
1543
1609
|
);
|
|
1610
|
+
const totalTokens = response.metadata?.usage?.totalTokens || 0;
|
|
1611
|
+
if (usageRequestId) {
|
|
1612
|
+
await reportAiUsage(
|
|
1613
|
+
this.http,
|
|
1614
|
+
usageRequestId,
|
|
1615
|
+
params.model,
|
|
1616
|
+
"embeddings",
|
|
1617
|
+
totalTokens
|
|
1618
|
+
);
|
|
1619
|
+
}
|
|
1544
1620
|
return {
|
|
1545
1621
|
object: response.object,
|
|
1546
1622
|
data: response.data,
|
|
1547
1623
|
model: response.metadata?.model,
|
|
1548
1624
|
usage: response.metadata?.usage ? {
|
|
1549
1625
|
prompt_tokens: response.metadata.usage.promptTokens || 0,
|
|
1550
|
-
total_tokens:
|
|
1626
|
+
total_tokens: totalTokens
|
|
1551
1627
|
} : {
|
|
1552
1628
|
prompt_tokens: 0,
|
|
1553
1629
|
total_tokens: 0
|
|
@@ -1585,6 +1661,7 @@ var Images = class {
|
|
|
1585
1661
|
* ```
|
|
1586
1662
|
*/
|
|
1587
1663
|
async generate(params) {
|
|
1664
|
+
const usageRequestId = aiUsageRequestId();
|
|
1588
1665
|
const response = await this.http.post(
|
|
1589
1666
|
"/api/ai/image/generation",
|
|
1590
1667
|
params
|
|
@@ -1598,6 +1675,16 @@ var Images = class {
|
|
|
1598
1675
|
} else if (response.text) {
|
|
1599
1676
|
data = [{ content: response.text }];
|
|
1600
1677
|
}
|
|
1678
|
+
const totalTokens = response.metadata?.usage?.totalTokens || 0;
|
|
1679
|
+
if (usageRequestId) {
|
|
1680
|
+
await reportAiUsage(
|
|
1681
|
+
this.http,
|
|
1682
|
+
usageRequestId,
|
|
1683
|
+
params.model,
|
|
1684
|
+
"image",
|
|
1685
|
+
totalTokens
|
|
1686
|
+
);
|
|
1687
|
+
}
|
|
1601
1688
|
return {
|
|
1602
1689
|
created: Math.floor(Date.now() / 1e3),
|
|
1603
1690
|
data,
|
package/dist/ssr.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { R as ResultClient } from './client-
|
|
2
|
-
import { o as ResultError, a as ResultConfig, G as AuthRefreshResponse } from './types-
|
|
3
|
-
import { A as AuthCookieSettings, C as CookieStore, a as CookieWriter } from './middleware-
|
|
4
|
-
export { b as AuthCookieNames, c as AuthCookieOptions, d as CookieOptions, e as CookieReader, D as DEFAULT_ACCESS_TOKEN_COOKIE, f as DEFAULT_REFRESH_TOKEN_COOKIE, U as UpdateSessionOptions, g as UpdateSessionResult, h as accessTokenCookieOptions, i as clearAuthCookies, j as getAccessTokenCookieName, k as getRefreshTokenCookieName, r as refreshTokenCookieOptions, s as setAuthCookies, u as updateSession } from './middleware-
|
|
1
|
+
import { R as ResultClient } from './client-N6MW9IE1.cjs';
|
|
2
|
+
import { o as ResultError, a as ResultConfig, G as AuthRefreshResponse } from './types-BTdjI7Yj.cjs';
|
|
3
|
+
import { A as AuthCookieSettings, C as CookieStore, a as CookieWriter } from './middleware-CGn44ocX.cjs';
|
|
4
|
+
export { b as AuthCookieNames, c as AuthCookieOptions, d as CookieOptions, e as CookieReader, D as DEFAULT_ACCESS_TOKEN_COOKIE, f as DEFAULT_REFRESH_TOKEN_COOKIE, U as UpdateSessionOptions, g as UpdateSessionResult, h as accessTokenCookieOptions, i as clearAuthCookies, j as getAccessTokenCookieName, k as getRefreshTokenCookieName, r as refreshTokenCookieOptions, s as setAuthCookies, u as updateSession } from './middleware-CGn44ocX.cjs';
|
|
5
5
|
import '@supabase/postgrest-js';
|
|
6
6
|
|
|
7
7
|
interface CreateAuthActionsOptions extends Omit<ResultConfig, "accessToken" | "edgeFunctionToken" | "isServerMode" | "auth">, AuthCookieSettings {
|
package/dist/ssr.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { R as ResultClient } from './client
|
|
2
|
-
import { o as ResultError, a as ResultConfig, G as AuthRefreshResponse } from './types-
|
|
3
|
-
import { A as AuthCookieSettings, C as CookieStore, a as CookieWriter } from './middleware-
|
|
4
|
-
export { b as AuthCookieNames, c as AuthCookieOptions, d as CookieOptions, e as CookieReader, D as DEFAULT_ACCESS_TOKEN_COOKIE, f as DEFAULT_REFRESH_TOKEN_COOKIE, U as UpdateSessionOptions, g as UpdateSessionResult, h as accessTokenCookieOptions, i as clearAuthCookies, j as getAccessTokenCookieName, k as getRefreshTokenCookieName, r as refreshTokenCookieOptions, s as setAuthCookies, u as updateSession } from './middleware-
|
|
1
|
+
import { R as ResultClient } from './client-D5IGLPW4.js';
|
|
2
|
+
import { o as ResultError, a as ResultConfig, G as AuthRefreshResponse } from './types-BTdjI7Yj.js';
|
|
3
|
+
import { A as AuthCookieSettings, C as CookieStore, a as CookieWriter } from './middleware-8UNqItQG.js';
|
|
4
|
+
export { b as AuthCookieNames, c as AuthCookieOptions, d as CookieOptions, e as CookieReader, D as DEFAULT_ACCESS_TOKEN_COOKIE, f as DEFAULT_REFRESH_TOKEN_COOKIE, U as UpdateSessionOptions, g as UpdateSessionResult, h as accessTokenCookieOptions, i as clearAuthCookies, j as getAccessTokenCookieName, k as getRefreshTokenCookieName, r as refreshTokenCookieOptions, s as setAuthCookies, u as updateSession } from './middleware-8UNqItQG.js';
|
|
5
5
|
import '@supabase/postgrest-js';
|
|
6
6
|
|
|
7
7
|
interface CreateAuthActionsOptions extends Omit<ResultConfig, "accessToken" | "edgeFunctionToken" | "isServerMode" | "auth">, AuthCookieSettings {
|
package/dist/ssr.js
CHANGED
|
@@ -740,6 +740,7 @@ var HttpClient = class {
|
|
|
740
740
|
}
|
|
741
741
|
let controller;
|
|
742
742
|
let timer;
|
|
743
|
+
let removeCallerAbortListener;
|
|
743
744
|
if (this.timeout > 0 || callerSignal) {
|
|
744
745
|
controller = new AbortController();
|
|
745
746
|
if (this.timeout > 0) {
|
|
@@ -753,16 +754,11 @@ var HttpClient = class {
|
|
|
753
754
|
callerSignal.addEventListener("abort", onCallerAbort, {
|
|
754
755
|
once: true
|
|
755
756
|
});
|
|
756
|
-
|
|
757
|
-
"abort",
|
|
758
|
-
() => {
|
|
759
|
-
callerSignal.removeEventListener("abort", onCallerAbort);
|
|
760
|
-
},
|
|
761
|
-
{ once: true }
|
|
762
|
-
);
|
|
757
|
+
removeCallerAbortListener = () => callerSignal.removeEventListener("abort", onCallerAbort);
|
|
763
758
|
}
|
|
764
759
|
}
|
|
765
760
|
}
|
|
761
|
+
let detachOnExit = true;
|
|
766
762
|
try {
|
|
767
763
|
const response = await this.fetch(url, {
|
|
768
764
|
method,
|
|
@@ -783,14 +779,9 @@ var HttpClient = class {
|
|
|
783
779
|
);
|
|
784
780
|
continue;
|
|
785
781
|
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
}
|
|
789
|
-
return response;
|
|
782
|
+
detachOnExit = false;
|
|
783
|
+
return { response, releaseCallerSignal: removeCallerAbortListener };
|
|
790
784
|
} catch (err) {
|
|
791
|
-
if (timer !== void 0) {
|
|
792
|
-
clearTimeout(timer);
|
|
793
|
-
}
|
|
794
785
|
if (err?.name === "AbortError") {
|
|
795
786
|
if (controller?.signal.aborted && this.timeout > 0 && !callerSignal?.aborted) {
|
|
796
787
|
throw new ResultError(
|
|
@@ -810,6 +801,13 @@ var HttpClient = class {
|
|
|
810
801
|
0,
|
|
811
802
|
"NETWORK_ERROR"
|
|
812
803
|
);
|
|
804
|
+
} finally {
|
|
805
|
+
if (timer !== void 0) {
|
|
806
|
+
clearTimeout(timer);
|
|
807
|
+
}
|
|
808
|
+
if (detachOnExit) {
|
|
809
|
+
removeCallerAbortListener?.();
|
|
810
|
+
}
|
|
813
811
|
}
|
|
814
812
|
}
|
|
815
813
|
throw lastError || new ResultError(
|
|
@@ -872,7 +870,7 @@ var HttpClient = class {
|
|
|
872
870
|
});
|
|
873
871
|
}
|
|
874
872
|
this.logger.logRequest(method, url, requestHeaders, processedBody);
|
|
875
|
-
const response = await this.fetchWithRetry({
|
|
873
|
+
const { response, releaseCallerSignal } = await this.fetchWithRetry({
|
|
876
874
|
method,
|
|
877
875
|
url,
|
|
878
876
|
headers: requestHeaders,
|
|
@@ -895,6 +893,8 @@ var HttpClient = class {
|
|
|
895
893
|
);
|
|
896
894
|
}
|
|
897
895
|
throw err;
|
|
896
|
+
} finally {
|
|
897
|
+
releaseCallerSignal?.();
|
|
898
898
|
}
|
|
899
899
|
this.logger.logResponse(
|
|
900
900
|
method,
|
|
@@ -996,7 +996,7 @@ var HttpClient = class {
|
|
|
996
996
|
const callerSignal = initSignal ?? request?.signal;
|
|
997
997
|
const maxAttempts = IDEMPOTENT_METHODS.has(method.toUpperCase()) ? this.retryCount : 0;
|
|
998
998
|
this.logger.logRequest(method, url, requestHeaders, body);
|
|
999
|
-
const response = await this.fetchWithRetry({
|
|
999
|
+
const { response } = await this.fetchWithRetry({
|
|
1000
1000
|
method,
|
|
1001
1001
|
url,
|
|
1002
1002
|
headers: requestHeaders,
|
|
@@ -1097,6 +1097,10 @@ var HttpClient = class {
|
|
|
1097
1097
|
}
|
|
1098
1098
|
return headers;
|
|
1099
1099
|
}
|
|
1100
|
+
/** Returns the publishable project key used to identify SDK usage reports. */
|
|
1101
|
+
getAnonKey() {
|
|
1102
|
+
return this.anonKey;
|
|
1103
|
+
}
|
|
1100
1104
|
async refreshAccessToken() {
|
|
1101
1105
|
if (this.isRefreshing) {
|
|
1102
1106
|
return this.refreshPromise;
|
|
@@ -1166,6 +1170,47 @@ var HttpClient = class {
|
|
|
1166
1170
|
}
|
|
1167
1171
|
};
|
|
1168
1172
|
|
|
1173
|
+
// src/modules/ai-usage.ts
|
|
1174
|
+
var USAGE_ENDPOINT = "https://beta.result.dev/api/usage/ai";
|
|
1175
|
+
async function reportAiUsage(http, requestId, model, kind, tokens) {
|
|
1176
|
+
const anonKey = http.getAnonKey();
|
|
1177
|
+
if (!anonKey || !Number.isSafeInteger(tokens) || tokens <= 0) {
|
|
1178
|
+
return;
|
|
1179
|
+
}
|
|
1180
|
+
const controller = new AbortController();
|
|
1181
|
+
const timeout = setTimeout(() => controller.abort(), 2e3);
|
|
1182
|
+
try {
|
|
1183
|
+
const request = {
|
|
1184
|
+
method: "POST",
|
|
1185
|
+
headers: { "content-type": "application/json" },
|
|
1186
|
+
body: JSON.stringify({
|
|
1187
|
+
requestId,
|
|
1188
|
+
backendUrl: http.baseUrl,
|
|
1189
|
+
anonKey,
|
|
1190
|
+
model,
|
|
1191
|
+
kind,
|
|
1192
|
+
tokens
|
|
1193
|
+
}),
|
|
1194
|
+
keepalive: true,
|
|
1195
|
+
signal: controller.signal
|
|
1196
|
+
};
|
|
1197
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
1198
|
+
try {
|
|
1199
|
+
const response = await http.fetch(USAGE_ENDPOINT, request);
|
|
1200
|
+
if (response.status < 500) return;
|
|
1201
|
+
} catch {
|
|
1202
|
+
if (controller.signal.aborted) return;
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
} catch {
|
|
1206
|
+
} finally {
|
|
1207
|
+
clearTimeout(timeout);
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
function aiUsageRequestId() {
|
|
1211
|
+
return globalThis.crypto?.randomUUID?.() ?? null;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1169
1214
|
// src/modules/ai.ts
|
|
1170
1215
|
var SUPPORTED_AUDIO_FORMATS = [
|
|
1171
1216
|
"wav",
|
|
@@ -1253,6 +1298,7 @@ var ChatCompletions = class {
|
|
|
1253
1298
|
}
|
|
1254
1299
|
http;
|
|
1255
1300
|
async create(params) {
|
|
1301
|
+
const usageRequestId = aiUsageRequestId();
|
|
1256
1302
|
const contentSummary = summarizeContent(params.messages ?? []);
|
|
1257
1303
|
assertSupportedContent(params.model, contentSummary);
|
|
1258
1304
|
const backendParams = {
|
|
@@ -1297,7 +1343,7 @@ var ChatCompletions = class {
|
|
|
1297
1343
|
contentSummary
|
|
1298
1344
|
);
|
|
1299
1345
|
}
|
|
1300
|
-
return this.parseSSEStream(response2, params.model);
|
|
1346
|
+
return this.parseSSEStream(response2, params.model, usageRequestId);
|
|
1301
1347
|
}
|
|
1302
1348
|
let response;
|
|
1303
1349
|
try {
|
|
@@ -1306,6 +1352,16 @@ var ChatCompletions = class {
|
|
|
1306
1352
|
throw enrichUpstreamError(error, contentSummary);
|
|
1307
1353
|
}
|
|
1308
1354
|
const content = response.text || "";
|
|
1355
|
+
const totalTokens = response.metadata?.usage?.totalTokens || 0;
|
|
1356
|
+
if (usageRequestId) {
|
|
1357
|
+
await reportAiUsage(
|
|
1358
|
+
this.http,
|
|
1359
|
+
usageRequestId,
|
|
1360
|
+
params.model,
|
|
1361
|
+
"chat",
|
|
1362
|
+
totalTokens
|
|
1363
|
+
);
|
|
1364
|
+
}
|
|
1309
1365
|
return {
|
|
1310
1366
|
id: `chatcmpl-${Date.now()}`,
|
|
1311
1367
|
object: "chat.completion",
|
|
@@ -1332,14 +1388,14 @@ var ChatCompletions = class {
|
|
|
1332
1388
|
usage: {
|
|
1333
1389
|
prompt_tokens: response.metadata?.usage?.promptTokens || 0,
|
|
1334
1390
|
completion_tokens: response.metadata?.usage?.completionTokens || 0,
|
|
1335
|
-
total_tokens:
|
|
1391
|
+
total_tokens: totalTokens
|
|
1336
1392
|
}
|
|
1337
1393
|
};
|
|
1338
1394
|
}
|
|
1339
1395
|
/**
|
|
1340
1396
|
* Parse SSE stream into async iterable of OpenAI-like chunks
|
|
1341
1397
|
*/
|
|
1342
|
-
async *parseSSEStream(response, model) {
|
|
1398
|
+
async *parseSSEStream(response, model, usageRequestId) {
|
|
1343
1399
|
const reader = response.body?.getReader();
|
|
1344
1400
|
if (!reader) {
|
|
1345
1401
|
throw new ResultError(
|
|
@@ -1417,6 +1473,15 @@ var ChatCompletions = class {
|
|
|
1417
1473
|
};
|
|
1418
1474
|
}
|
|
1419
1475
|
if (data.tokenUsage) {
|
|
1476
|
+
if (usageRequestId) {
|
|
1477
|
+
await reportAiUsage(
|
|
1478
|
+
this.http,
|
|
1479
|
+
usageRequestId,
|
|
1480
|
+
model,
|
|
1481
|
+
"chat",
|
|
1482
|
+
data.tokenUsage.totalTokens || 0
|
|
1483
|
+
);
|
|
1484
|
+
}
|
|
1420
1485
|
yield {
|
|
1421
1486
|
id: `chatcmpl-${Date.now()}`,
|
|
1422
1487
|
object: "chat.completion.chunk",
|
|
@@ -1488,17 +1553,28 @@ var Embeddings = class {
|
|
|
1488
1553
|
* ```
|
|
1489
1554
|
*/
|
|
1490
1555
|
async create(params) {
|
|
1556
|
+
const usageRequestId = aiUsageRequestId();
|
|
1491
1557
|
const response = await this.http.post(
|
|
1492
1558
|
"/api/ai/embeddings",
|
|
1493
1559
|
params
|
|
1494
1560
|
);
|
|
1561
|
+
const totalTokens = response.metadata?.usage?.totalTokens || 0;
|
|
1562
|
+
if (usageRequestId) {
|
|
1563
|
+
await reportAiUsage(
|
|
1564
|
+
this.http,
|
|
1565
|
+
usageRequestId,
|
|
1566
|
+
params.model,
|
|
1567
|
+
"embeddings",
|
|
1568
|
+
totalTokens
|
|
1569
|
+
);
|
|
1570
|
+
}
|
|
1495
1571
|
return {
|
|
1496
1572
|
object: response.object,
|
|
1497
1573
|
data: response.data,
|
|
1498
1574
|
model: response.metadata?.model,
|
|
1499
1575
|
usage: response.metadata?.usage ? {
|
|
1500
1576
|
prompt_tokens: response.metadata.usage.promptTokens || 0,
|
|
1501
|
-
total_tokens:
|
|
1577
|
+
total_tokens: totalTokens
|
|
1502
1578
|
} : {
|
|
1503
1579
|
prompt_tokens: 0,
|
|
1504
1580
|
total_tokens: 0
|
|
@@ -1536,6 +1612,7 @@ var Images = class {
|
|
|
1536
1612
|
* ```
|
|
1537
1613
|
*/
|
|
1538
1614
|
async generate(params) {
|
|
1615
|
+
const usageRequestId = aiUsageRequestId();
|
|
1539
1616
|
const response = await this.http.post(
|
|
1540
1617
|
"/api/ai/image/generation",
|
|
1541
1618
|
params
|
|
@@ -1549,6 +1626,16 @@ var Images = class {
|
|
|
1549
1626
|
} else if (response.text) {
|
|
1550
1627
|
data = [{ content: response.text }];
|
|
1551
1628
|
}
|
|
1629
|
+
const totalTokens = response.metadata?.usage?.totalTokens || 0;
|
|
1630
|
+
if (usageRequestId) {
|
|
1631
|
+
await reportAiUsage(
|
|
1632
|
+
this.http,
|
|
1633
|
+
usageRequestId,
|
|
1634
|
+
params.model,
|
|
1635
|
+
"image",
|
|
1636
|
+
totalTokens
|
|
1637
|
+
);
|
|
1638
|
+
}
|
|
1552
1639
|
return {
|
|
1553
1640
|
created: Math.floor(Date.now() / 1e3),
|
|
1554
1641
|
data,
|
|
@@ -528,7 +528,8 @@ interface ResultConfig {
|
|
|
528
528
|
/**
|
|
529
529
|
* The base URL of the Result backend API (the NEXT_PUBLIC_BACKEND_URL
|
|
530
530
|
* value from .env.local). Required at runtime: constructing a client
|
|
531
|
-
* without it throws MISSING_BASE_URL.
|
|
531
|
+
* without it throws MISSING_BASE_URL. (Kept optional in the type because
|
|
532
|
+
* the SSR entrypoints intentionally fill it from process.env.)
|
|
532
533
|
*/
|
|
533
534
|
baseUrl?: string;
|
|
534
535
|
/**
|
|
@@ -528,7 +528,8 @@ interface ResultConfig {
|
|
|
528
528
|
/**
|
|
529
529
|
* The base URL of the Result backend API (the NEXT_PUBLIC_BACKEND_URL
|
|
530
530
|
* value from .env.local). Required at runtime: constructing a client
|
|
531
|
-
* without it throws MISSING_BASE_URL.
|
|
531
|
+
* without it throws MISSING_BASE_URL. (Kept optional in the type because
|
|
532
|
+
* the SSR entrypoints intentionally fill it from process.env.)
|
|
532
533
|
*/
|
|
533
534
|
baseUrl?: string;
|
|
534
535
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@resultdev/sdk",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Result Backend SDK - authentication, database, storage, functions, realtime, AI, email, web analytics and customer support for apps built on Result.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"homepage": "https://docs.result.dev",
|
|
@@ -59,8 +59,19 @@
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
},
|
|
62
|
+
"scripts": {
|
|
63
|
+
"build": "tsup",
|
|
64
|
+
"test": "vitest run",
|
|
65
|
+
"check-types": "tsc --noEmit -p tsconfig.json"
|
|
66
|
+
},
|
|
62
67
|
"dependencies": {
|
|
63
68
|
"@supabase/postgrest-js": "^1.21.3",
|
|
64
69
|
"socket.io-client": "^4.8.1"
|
|
70
|
+
},
|
|
71
|
+
"devDependencies": {
|
|
72
|
+
"@types/node": "^24.0.0",
|
|
73
|
+
"tsup": "^8.5.0",
|
|
74
|
+
"typescript": "^5.9.2",
|
|
75
|
+
"vitest": "^3.2.4"
|
|
65
76
|
}
|
|
66
|
-
}
|
|
77
|
+
}
|