@resultdev/sdk 0.2.0 → 0.3.1
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 +43 -0
- package/dist/{client-DeE086La.d.cts → client--Xjaaw1l.d.ts} +62 -32
- package/dist/{client-Z0zUHGE3.d.ts → client-BrOD2EO5.d.cts} +62 -32
- package/dist/index.cjs +170 -20
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +170 -20
- package/dist/{middleware-TGaDOhE9.d.ts → middleware-Uh09_lFn.d.ts} +1 -1
- package/dist/{middleware-BBY_6hyx.d.cts → middleware-VCWoai4o.d.cts} +1 -1
- package/dist/ssr/middleware.d.cts +2 -2
- package/dist/ssr/middleware.d.ts +2 -2
- package/dist/ssr.cjs +170 -20
- package/dist/ssr.d.cts +4 -4
- package/dist/ssr.d.ts +4 -4
- package/dist/ssr.js +170 -20
- package/dist/{types-CbsaMttt.d.cts → types-BmU3deRO.d.cts} +12 -3
- package/dist/{types-CbsaMttt.d.ts → types-BmU3deRO.d.ts} +12 -3
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -503,7 +503,15 @@ var HttpClient = class {
|
|
|
503
503
|
*/
|
|
504
504
|
constructor(config, tokenManager, logger) {
|
|
505
505
|
this.config = config;
|
|
506
|
-
|
|
506
|
+
if (!config.baseUrl) {
|
|
507
|
+
throw new ResultError(
|
|
508
|
+
"createClient needs a baseUrl, but it was undefined at runtime.",
|
|
509
|
+
0,
|
|
510
|
+
"MISSING_BASE_URL",
|
|
511
|
+
"Pass the NEXT_PUBLIC_BACKEND_URL value from .env.local. In browser code, write process.env.NEXT_PUBLIC_BACKEND_URL as a literal expression (never through an imported process module) so the bundler inlines it, and set it as a deployments build variable before deploying."
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
this.baseUrl = config.baseUrl;
|
|
507
515
|
this.fetch = config.fetch || (globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
|
|
508
516
|
this.anonKey = config.anonKey;
|
|
509
517
|
this.defaultHeaders = {
|
|
@@ -1021,6 +1029,70 @@ var HttpClient = class {
|
|
|
1021
1029
|
};
|
|
1022
1030
|
|
|
1023
1031
|
// src/modules/ai.ts
|
|
1032
|
+
var SUPPORTED_AUDIO_FORMATS = [
|
|
1033
|
+
"wav",
|
|
1034
|
+
"mp3",
|
|
1035
|
+
"aiff",
|
|
1036
|
+
"aac",
|
|
1037
|
+
"ogg",
|
|
1038
|
+
"flac",
|
|
1039
|
+
"m4a"
|
|
1040
|
+
];
|
|
1041
|
+
var MULTIMODAL_MODEL = "google/gemini-2.5-flash";
|
|
1042
|
+
function summarizeContent(messages) {
|
|
1043
|
+
const summary = {
|
|
1044
|
+
hasImage: false,
|
|
1045
|
+
hasAudio: false,
|
|
1046
|
+
badAudioFormats: []
|
|
1047
|
+
};
|
|
1048
|
+
for (const message of messages) {
|
|
1049
|
+
if (message.images?.length) {
|
|
1050
|
+
summary.hasImage = true;
|
|
1051
|
+
}
|
|
1052
|
+
if (!Array.isArray(message.content)) {
|
|
1053
|
+
continue;
|
|
1054
|
+
}
|
|
1055
|
+
for (const part of message.content) {
|
|
1056
|
+
if (part?.type === "image_url") {
|
|
1057
|
+
summary.hasImage = true;
|
|
1058
|
+
} else if (part?.type === "input_audio") {
|
|
1059
|
+
summary.hasAudio = true;
|
|
1060
|
+
const format2 = part.input_audio?.format;
|
|
1061
|
+
if (format2 && !SUPPORTED_AUDIO_FORMATS.includes(format2)) {
|
|
1062
|
+
summary.badAudioFormats.push(format2);
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
return summary;
|
|
1068
|
+
}
|
|
1069
|
+
function assertSupportedContent(model, summary) {
|
|
1070
|
+
if (summary.badAudioFormats.length) {
|
|
1071
|
+
throw new ResultError(
|
|
1072
|
+
`Audio format "${summary.badAudioFormats[0]}" is not supported. Supported formats: ${SUPPORTED_AUDIO_FORMATS.join(", ")}. Browser MediaRecorder produces webm/opus, which the gateway rejects - capture PCM with the Web Audio API and encode a 16 kHz mono WAV instead.`,
|
|
1073
|
+
400,
|
|
1074
|
+
"AI_INVALID_INPUT"
|
|
1075
|
+
);
|
|
1076
|
+
}
|
|
1077
|
+
if (summary.hasAudio && model.startsWith("openai/")) {
|
|
1078
|
+
throw new ResultError(
|
|
1079
|
+
`Model "${model}" does not accept audio input on this gateway. Use ${MULTIMODAL_MODEL} (verified for audio).`,
|
|
1080
|
+
400,
|
|
1081
|
+
"AI_INVALID_INPUT"
|
|
1082
|
+
);
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
function enrichUpstreamError(error, summary) {
|
|
1086
|
+
if (!(error instanceof ResultError) || error.error !== "AI_UPSTREAM_UNAVAILABLE" || !summary.hasImage && !summary.hasAudio) {
|
|
1087
|
+
return error;
|
|
1088
|
+
}
|
|
1089
|
+
const kind = summary.hasImage && summary.hasAudio ? "image and audio" : summary.hasImage ? "image" : "audio";
|
|
1090
|
+
return new ResultError(
|
|
1091
|
+
`${error.message} This request included ${kind} input; if the error persists, use ${MULTIMODAL_MODEL} (verified for vision and audio).`,
|
|
1092
|
+
error.statusCode,
|
|
1093
|
+
error.error
|
|
1094
|
+
);
|
|
1095
|
+
}
|
|
1024
1096
|
var AI = class {
|
|
1025
1097
|
chat;
|
|
1026
1098
|
images;
|
|
@@ -1043,6 +1115,8 @@ var ChatCompletions = class {
|
|
|
1043
1115
|
}
|
|
1044
1116
|
http;
|
|
1045
1117
|
async create(params) {
|
|
1118
|
+
const contentSummary = summarizeContent(params.messages ?? []);
|
|
1119
|
+
assertSupportedContent(params.model, contentSummary);
|
|
1046
1120
|
const backendParams = {
|
|
1047
1121
|
model: params.model,
|
|
1048
1122
|
messages: params.messages,
|
|
@@ -1071,15 +1145,28 @@ var ChatCompletions = class {
|
|
|
1071
1145
|
}
|
|
1072
1146
|
);
|
|
1073
1147
|
if (!response2.ok) {
|
|
1074
|
-
|
|
1075
|
-
|
|
1148
|
+
let body = null;
|
|
1149
|
+
try {
|
|
1150
|
+
body = await response2.json();
|
|
1151
|
+
} catch {
|
|
1152
|
+
}
|
|
1153
|
+
throw enrichUpstreamError(
|
|
1154
|
+
new ResultError(
|
|
1155
|
+
body?.message || body?.error || "Stream request failed",
|
|
1156
|
+
body?.statusCode ?? response2.status,
|
|
1157
|
+
body?.error || "AI_STREAM_ERROR"
|
|
1158
|
+
),
|
|
1159
|
+
contentSummary
|
|
1160
|
+
);
|
|
1076
1161
|
}
|
|
1077
1162
|
return this.parseSSEStream(response2, params.model);
|
|
1078
1163
|
}
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
backendParams
|
|
1082
|
-
)
|
|
1164
|
+
let response;
|
|
1165
|
+
try {
|
|
1166
|
+
response = await this.http.post("/api/ai/chat/completion", backendParams);
|
|
1167
|
+
} catch (error) {
|
|
1168
|
+
throw enrichUpstreamError(error, contentSummary);
|
|
1169
|
+
}
|
|
1083
1170
|
const content = response.text || "";
|
|
1084
1171
|
return {
|
|
1085
1172
|
id: `chatcmpl-${Date.now()}`,
|
|
@@ -1174,6 +1261,37 @@ var ChatCompletions = class {
|
|
|
1174
1261
|
]
|
|
1175
1262
|
};
|
|
1176
1263
|
}
|
|
1264
|
+
if (data.annotations?.length) {
|
|
1265
|
+
yield {
|
|
1266
|
+
id: `chatcmpl-${Date.now()}`,
|
|
1267
|
+
object: "chat.completion.chunk",
|
|
1268
|
+
created: Math.floor(Date.now() / 1e3),
|
|
1269
|
+
model,
|
|
1270
|
+
choices: [
|
|
1271
|
+
{
|
|
1272
|
+
index: 0,
|
|
1273
|
+
delta: {
|
|
1274
|
+
annotations: data.annotations
|
|
1275
|
+
},
|
|
1276
|
+
finish_reason: null
|
|
1277
|
+
}
|
|
1278
|
+
]
|
|
1279
|
+
};
|
|
1280
|
+
}
|
|
1281
|
+
if (data.tokenUsage) {
|
|
1282
|
+
yield {
|
|
1283
|
+
id: `chatcmpl-${Date.now()}`,
|
|
1284
|
+
object: "chat.completion.chunk",
|
|
1285
|
+
created: Math.floor(Date.now() / 1e3),
|
|
1286
|
+
model,
|
|
1287
|
+
choices: [],
|
|
1288
|
+
usage: {
|
|
1289
|
+
prompt_tokens: data.tokenUsage.promptTokens || 0,
|
|
1290
|
+
completion_tokens: data.tokenUsage.completionTokens || 0,
|
|
1291
|
+
total_tokens: data.tokenUsage.totalTokens || 0
|
|
1292
|
+
}
|
|
1293
|
+
};
|
|
1294
|
+
}
|
|
1177
1295
|
if (data.done) {
|
|
1178
1296
|
reader.releaseLock();
|
|
1179
1297
|
return;
|
|
@@ -2410,13 +2528,13 @@ var Functions = class _Functions {
|
|
|
2410
2528
|
functionsUrl;
|
|
2411
2529
|
constructor(http, functionsUrl) {
|
|
2412
2530
|
this.http = http;
|
|
2413
|
-
this.functionsUrl = functionsUrl
|
|
2531
|
+
this.functionsUrl = functionsUrl;
|
|
2414
2532
|
}
|
|
2415
2533
|
/**
|
|
2416
|
-
* Derive the subhosting URL from the base URL
|
|
2417
|
-
* Rewrites the backend base URL to its functions subhosting URL
|
|
2534
|
+
* Derive the legacy subhosting URL from the base URL
|
|
2418
2535
|
* ({appKey}.{region}.<domain> -> {appKey}.functions.<domain>).
|
|
2419
|
-
* Only
|
|
2536
|
+
* Only used to recognize when a configured functionsUrl still points at
|
|
2537
|
+
* the local deployment, so in-process dispatch can short-circuit it.
|
|
2420
2538
|
*/
|
|
2421
2539
|
static deriveSubhostingUrl(baseUrl) {
|
|
2422
2540
|
try {
|
|
@@ -2449,11 +2567,13 @@ var Functions = class _Functions {
|
|
|
2449
2567
|
* Invoke an Edge Function.
|
|
2450
2568
|
*
|
|
2451
2569
|
* Dispatch order:
|
|
2452
|
-
* 1. If the platform's in-process dispatch hook is present
|
|
2453
|
-
*
|
|
2454
|
-
*
|
|
2455
|
-
* 2.
|
|
2456
|
-
*
|
|
2570
|
+
* 1. If the platform's in-process dispatch hook is present and no foreign
|
|
2571
|
+
* functionsUrl is configured, call it directly (function-to-function
|
|
2572
|
+
* calls inside the same deployment).
|
|
2573
|
+
* 2. If a custom functionsUrl is configured, try it; fall back to the
|
|
2574
|
+
* proxy path on 404 or network failure.
|
|
2575
|
+
* 3. Otherwise, invoke through the main host's /functions/{slug} proxy.
|
|
2576
|
+
* This route works from browsers too (correct CORS).
|
|
2457
2577
|
*
|
|
2458
2578
|
* @param slug The function slug to invoke
|
|
2459
2579
|
* @param options Request options
|
|
@@ -2462,7 +2582,7 @@ var Functions = class _Functions {
|
|
|
2462
2582
|
const { method = "POST", body, headers = {} } = options;
|
|
2463
2583
|
const dispatch = globalThis.__insforge_dispatch__;
|
|
2464
2584
|
const localFunctionsUrl = _Functions.deriveSubhostingUrl(this.http.baseUrl);
|
|
2465
|
-
if (typeof dispatch === "function" && !!localFunctionsUrl && this.functionsUrl === localFunctionsUrl) {
|
|
2585
|
+
if (typeof dispatch === "function" && (this.functionsUrl === void 0 || !!localFunctionsUrl && this.functionsUrl === localFunctionsUrl)) {
|
|
2466
2586
|
try {
|
|
2467
2587
|
const req = this.buildInProcessRequest(slug, method, body, headers);
|
|
2468
2588
|
const res = await dispatch(req);
|
|
@@ -2497,7 +2617,8 @@ var Functions = class _Functions {
|
|
|
2497
2617
|
if (error instanceof Error && error.name === "AbortError") {
|
|
2498
2618
|
throw error;
|
|
2499
2619
|
}
|
|
2500
|
-
|
|
2620
|
+
const unreachable = error instanceof ResultError && (error.statusCode === 404 || error.statusCode === 0);
|
|
2621
|
+
if (unreachable) {
|
|
2501
2622
|
} else {
|
|
2502
2623
|
return {
|
|
2503
2624
|
data: null,
|
|
@@ -2533,6 +2654,17 @@ var Functions = class _Functions {
|
|
|
2533
2654
|
// src/modules/realtime.ts
|
|
2534
2655
|
var CONNECT_TIMEOUT = 1e4;
|
|
2535
2656
|
var SUBSCRIBE_TIMEOUT = 1e4;
|
|
2657
|
+
var CHANNEL_PREFIX = "realtime:";
|
|
2658
|
+
function normalizeChannelMeta(message) {
|
|
2659
|
+
const channel = message?.meta?.channel;
|
|
2660
|
+
if (typeof channel !== "string" || !channel.startsWith(CHANNEL_PREFIX)) {
|
|
2661
|
+
return message;
|
|
2662
|
+
}
|
|
2663
|
+
return {
|
|
2664
|
+
...message,
|
|
2665
|
+
meta: { ...message.meta, channel: channel.slice(CHANNEL_PREFIX.length) }
|
|
2666
|
+
};
|
|
2667
|
+
}
|
|
2536
2668
|
var Realtime = class {
|
|
2537
2669
|
constructor(baseUrl, tokenManager, anonKey, getValidAccessToken = async () => tokenManager.getAccessToken()) {
|
|
2538
2670
|
this.baseUrl = baseUrl;
|
|
@@ -2654,8 +2786,9 @@ var Realtime = class {
|
|
|
2654
2786
|
if (event === "realtime:error") {
|
|
2655
2787
|
return;
|
|
2656
2788
|
}
|
|
2657
|
-
|
|
2658
|
-
this.
|
|
2789
|
+
const normalized = normalizeChannelMeta(message);
|
|
2790
|
+
this.applyPresenceEvent(event, normalized);
|
|
2791
|
+
this.notifyListeners(event, normalized);
|
|
2659
2792
|
};
|
|
2660
2793
|
this.connectionAttempt = { id: attemptId, socket, cancel: fail };
|
|
2661
2794
|
socket.on("connect", onConnect);
|
|
@@ -2903,6 +3036,17 @@ var Realtime = class {
|
|
|
2903
3036
|
this.socket.emit("realtime:unsubscribe", { channel });
|
|
2904
3037
|
}
|
|
2905
3038
|
}
|
|
3039
|
+
/**
|
|
3040
|
+
* Publish an event to a channel.
|
|
3041
|
+
*
|
|
3042
|
+
* Delivery notes (verified against a live backend):
|
|
3043
|
+
* - Payload fields arrive spread onto the received message itself, next to
|
|
3044
|
+
* `meta` - not nested under a `payload` key. Publishing `{ text: "hi" }`
|
|
3045
|
+
* means receivers read `msg.text`.
|
|
3046
|
+
* - The sender receives its own message too. Deduplicate with
|
|
3047
|
+
* `msg.meta.messageId` (or `msg.meta.senderId`) if you also update local
|
|
3048
|
+
* state optimistically.
|
|
3049
|
+
*/
|
|
2906
3050
|
async publish(channel, event, payload) {
|
|
2907
3051
|
if (!this.socket?.connected) {
|
|
2908
3052
|
throw new Error(
|
|
@@ -2911,6 +3055,12 @@ var Realtime = class {
|
|
|
2911
3055
|
}
|
|
2912
3056
|
this.socket.emit("realtime:publish", { channel, event, payload });
|
|
2913
3057
|
}
|
|
3058
|
+
/**
|
|
3059
|
+
* Listen for an event by name, across all subscribed channels.
|
|
3060
|
+
* Filter by channel inside the callback: `msg.meta.channel` always matches
|
|
3061
|
+
* the exact name passed to subscribe() (the SDK strips the server's
|
|
3062
|
+
* transport prefix before delivery).
|
|
3063
|
+
*/
|
|
2914
3064
|
on(event, callback) {
|
|
2915
3065
|
const listeners = this.eventListeners.get(event) ?? /* @__PURE__ */ new Set();
|
|
2916
3066
|
listeners.add(callback);
|
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-BrOD2EO5.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-BrOD2EO5.cjs';
|
|
3
|
+
import { R as ResultAdminConfig, a as ResultConfig } from './types-BmU3deRO.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-BmU3deRO.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--Xjaaw1l.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--Xjaaw1l.js';
|
|
3
|
+
import { R as ResultAdminConfig, a as ResultConfig } from './types-BmU3deRO.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-BmU3deRO.js';
|
|
5
5
|
import '@supabase/postgrest-js';
|
|
6
6
|
|
|
7
7
|
/**
|
package/dist/index.js
CHANGED
|
@@ -448,7 +448,15 @@ var HttpClient = class {
|
|
|
448
448
|
*/
|
|
449
449
|
constructor(config, tokenManager, logger) {
|
|
450
450
|
this.config = config;
|
|
451
|
-
|
|
451
|
+
if (!config.baseUrl) {
|
|
452
|
+
throw new ResultError(
|
|
453
|
+
"createClient needs a baseUrl, but it was undefined at runtime.",
|
|
454
|
+
0,
|
|
455
|
+
"MISSING_BASE_URL",
|
|
456
|
+
"Pass the NEXT_PUBLIC_BACKEND_URL value from .env.local. In browser code, write process.env.NEXT_PUBLIC_BACKEND_URL as a literal expression (never through an imported process module) so the bundler inlines it, and set it as a deployments build variable before deploying."
|
|
457
|
+
);
|
|
458
|
+
}
|
|
459
|
+
this.baseUrl = config.baseUrl;
|
|
452
460
|
this.fetch = config.fetch || (globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
|
|
453
461
|
this.anonKey = config.anonKey;
|
|
454
462
|
this.defaultHeaders = {
|
|
@@ -966,6 +974,70 @@ var HttpClient = class {
|
|
|
966
974
|
};
|
|
967
975
|
|
|
968
976
|
// src/modules/ai.ts
|
|
977
|
+
var SUPPORTED_AUDIO_FORMATS = [
|
|
978
|
+
"wav",
|
|
979
|
+
"mp3",
|
|
980
|
+
"aiff",
|
|
981
|
+
"aac",
|
|
982
|
+
"ogg",
|
|
983
|
+
"flac",
|
|
984
|
+
"m4a"
|
|
985
|
+
];
|
|
986
|
+
var MULTIMODAL_MODEL = "google/gemini-2.5-flash";
|
|
987
|
+
function summarizeContent(messages) {
|
|
988
|
+
const summary = {
|
|
989
|
+
hasImage: false,
|
|
990
|
+
hasAudio: false,
|
|
991
|
+
badAudioFormats: []
|
|
992
|
+
};
|
|
993
|
+
for (const message of messages) {
|
|
994
|
+
if (message.images?.length) {
|
|
995
|
+
summary.hasImage = true;
|
|
996
|
+
}
|
|
997
|
+
if (!Array.isArray(message.content)) {
|
|
998
|
+
continue;
|
|
999
|
+
}
|
|
1000
|
+
for (const part of message.content) {
|
|
1001
|
+
if (part?.type === "image_url") {
|
|
1002
|
+
summary.hasImage = true;
|
|
1003
|
+
} else if (part?.type === "input_audio") {
|
|
1004
|
+
summary.hasAudio = true;
|
|
1005
|
+
const format2 = part.input_audio?.format;
|
|
1006
|
+
if (format2 && !SUPPORTED_AUDIO_FORMATS.includes(format2)) {
|
|
1007
|
+
summary.badAudioFormats.push(format2);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
return summary;
|
|
1013
|
+
}
|
|
1014
|
+
function assertSupportedContent(model, summary) {
|
|
1015
|
+
if (summary.badAudioFormats.length) {
|
|
1016
|
+
throw new ResultError(
|
|
1017
|
+
`Audio format "${summary.badAudioFormats[0]}" is not supported. Supported formats: ${SUPPORTED_AUDIO_FORMATS.join(", ")}. Browser MediaRecorder produces webm/opus, which the gateway rejects - capture PCM with the Web Audio API and encode a 16 kHz mono WAV instead.`,
|
|
1018
|
+
400,
|
|
1019
|
+
"AI_INVALID_INPUT"
|
|
1020
|
+
);
|
|
1021
|
+
}
|
|
1022
|
+
if (summary.hasAudio && model.startsWith("openai/")) {
|
|
1023
|
+
throw new ResultError(
|
|
1024
|
+
`Model "${model}" does not accept audio input on this gateway. Use ${MULTIMODAL_MODEL} (verified for audio).`,
|
|
1025
|
+
400,
|
|
1026
|
+
"AI_INVALID_INPUT"
|
|
1027
|
+
);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
function enrichUpstreamError(error, summary) {
|
|
1031
|
+
if (!(error instanceof ResultError) || error.error !== "AI_UPSTREAM_UNAVAILABLE" || !summary.hasImage && !summary.hasAudio) {
|
|
1032
|
+
return error;
|
|
1033
|
+
}
|
|
1034
|
+
const kind = summary.hasImage && summary.hasAudio ? "image and audio" : summary.hasImage ? "image" : "audio";
|
|
1035
|
+
return new ResultError(
|
|
1036
|
+
`${error.message} This request included ${kind} input; if the error persists, use ${MULTIMODAL_MODEL} (verified for vision and audio).`,
|
|
1037
|
+
error.statusCode,
|
|
1038
|
+
error.error
|
|
1039
|
+
);
|
|
1040
|
+
}
|
|
969
1041
|
var AI = class {
|
|
970
1042
|
chat;
|
|
971
1043
|
images;
|
|
@@ -988,6 +1060,8 @@ var ChatCompletions = class {
|
|
|
988
1060
|
}
|
|
989
1061
|
http;
|
|
990
1062
|
async create(params) {
|
|
1063
|
+
const contentSummary = summarizeContent(params.messages ?? []);
|
|
1064
|
+
assertSupportedContent(params.model, contentSummary);
|
|
991
1065
|
const backendParams = {
|
|
992
1066
|
model: params.model,
|
|
993
1067
|
messages: params.messages,
|
|
@@ -1016,15 +1090,28 @@ var ChatCompletions = class {
|
|
|
1016
1090
|
}
|
|
1017
1091
|
);
|
|
1018
1092
|
if (!response2.ok) {
|
|
1019
|
-
|
|
1020
|
-
|
|
1093
|
+
let body = null;
|
|
1094
|
+
try {
|
|
1095
|
+
body = await response2.json();
|
|
1096
|
+
} catch {
|
|
1097
|
+
}
|
|
1098
|
+
throw enrichUpstreamError(
|
|
1099
|
+
new ResultError(
|
|
1100
|
+
body?.message || body?.error || "Stream request failed",
|
|
1101
|
+
body?.statusCode ?? response2.status,
|
|
1102
|
+
body?.error || "AI_STREAM_ERROR"
|
|
1103
|
+
),
|
|
1104
|
+
contentSummary
|
|
1105
|
+
);
|
|
1021
1106
|
}
|
|
1022
1107
|
return this.parseSSEStream(response2, params.model);
|
|
1023
1108
|
}
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
backendParams
|
|
1027
|
-
)
|
|
1109
|
+
let response;
|
|
1110
|
+
try {
|
|
1111
|
+
response = await this.http.post("/api/ai/chat/completion", backendParams);
|
|
1112
|
+
} catch (error) {
|
|
1113
|
+
throw enrichUpstreamError(error, contentSummary);
|
|
1114
|
+
}
|
|
1028
1115
|
const content = response.text || "";
|
|
1029
1116
|
return {
|
|
1030
1117
|
id: `chatcmpl-${Date.now()}`,
|
|
@@ -1119,6 +1206,37 @@ var ChatCompletions = class {
|
|
|
1119
1206
|
]
|
|
1120
1207
|
};
|
|
1121
1208
|
}
|
|
1209
|
+
if (data.annotations?.length) {
|
|
1210
|
+
yield {
|
|
1211
|
+
id: `chatcmpl-${Date.now()}`,
|
|
1212
|
+
object: "chat.completion.chunk",
|
|
1213
|
+
created: Math.floor(Date.now() / 1e3),
|
|
1214
|
+
model,
|
|
1215
|
+
choices: [
|
|
1216
|
+
{
|
|
1217
|
+
index: 0,
|
|
1218
|
+
delta: {
|
|
1219
|
+
annotations: data.annotations
|
|
1220
|
+
},
|
|
1221
|
+
finish_reason: null
|
|
1222
|
+
}
|
|
1223
|
+
]
|
|
1224
|
+
};
|
|
1225
|
+
}
|
|
1226
|
+
if (data.tokenUsage) {
|
|
1227
|
+
yield {
|
|
1228
|
+
id: `chatcmpl-${Date.now()}`,
|
|
1229
|
+
object: "chat.completion.chunk",
|
|
1230
|
+
created: Math.floor(Date.now() / 1e3),
|
|
1231
|
+
model,
|
|
1232
|
+
choices: [],
|
|
1233
|
+
usage: {
|
|
1234
|
+
prompt_tokens: data.tokenUsage.promptTokens || 0,
|
|
1235
|
+
completion_tokens: data.tokenUsage.completionTokens || 0,
|
|
1236
|
+
total_tokens: data.tokenUsage.totalTokens || 0
|
|
1237
|
+
}
|
|
1238
|
+
};
|
|
1239
|
+
}
|
|
1122
1240
|
if (data.done) {
|
|
1123
1241
|
reader.releaseLock();
|
|
1124
1242
|
return;
|
|
@@ -2355,13 +2473,13 @@ var Functions = class _Functions {
|
|
|
2355
2473
|
functionsUrl;
|
|
2356
2474
|
constructor(http, functionsUrl) {
|
|
2357
2475
|
this.http = http;
|
|
2358
|
-
this.functionsUrl = functionsUrl
|
|
2476
|
+
this.functionsUrl = functionsUrl;
|
|
2359
2477
|
}
|
|
2360
2478
|
/**
|
|
2361
|
-
* Derive the subhosting URL from the base URL
|
|
2362
|
-
* Rewrites the backend base URL to its functions subhosting URL
|
|
2479
|
+
* Derive the legacy subhosting URL from the base URL
|
|
2363
2480
|
* ({appKey}.{region}.<domain> -> {appKey}.functions.<domain>).
|
|
2364
|
-
* Only
|
|
2481
|
+
* Only used to recognize when a configured functionsUrl still points at
|
|
2482
|
+
* the local deployment, so in-process dispatch can short-circuit it.
|
|
2365
2483
|
*/
|
|
2366
2484
|
static deriveSubhostingUrl(baseUrl) {
|
|
2367
2485
|
try {
|
|
@@ -2394,11 +2512,13 @@ var Functions = class _Functions {
|
|
|
2394
2512
|
* Invoke an Edge Function.
|
|
2395
2513
|
*
|
|
2396
2514
|
* Dispatch order:
|
|
2397
|
-
* 1. If the platform's in-process dispatch hook is present
|
|
2398
|
-
*
|
|
2399
|
-
*
|
|
2400
|
-
* 2.
|
|
2401
|
-
*
|
|
2515
|
+
* 1. If the platform's in-process dispatch hook is present and no foreign
|
|
2516
|
+
* functionsUrl is configured, call it directly (function-to-function
|
|
2517
|
+
* calls inside the same deployment).
|
|
2518
|
+
* 2. If a custom functionsUrl is configured, try it; fall back to the
|
|
2519
|
+
* proxy path on 404 or network failure.
|
|
2520
|
+
* 3. Otherwise, invoke through the main host's /functions/{slug} proxy.
|
|
2521
|
+
* This route works from browsers too (correct CORS).
|
|
2402
2522
|
*
|
|
2403
2523
|
* @param slug The function slug to invoke
|
|
2404
2524
|
* @param options Request options
|
|
@@ -2407,7 +2527,7 @@ var Functions = class _Functions {
|
|
|
2407
2527
|
const { method = "POST", body, headers = {} } = options;
|
|
2408
2528
|
const dispatch = globalThis.__insforge_dispatch__;
|
|
2409
2529
|
const localFunctionsUrl = _Functions.deriveSubhostingUrl(this.http.baseUrl);
|
|
2410
|
-
if (typeof dispatch === "function" && !!localFunctionsUrl && this.functionsUrl === localFunctionsUrl) {
|
|
2530
|
+
if (typeof dispatch === "function" && (this.functionsUrl === void 0 || !!localFunctionsUrl && this.functionsUrl === localFunctionsUrl)) {
|
|
2411
2531
|
try {
|
|
2412
2532
|
const req = this.buildInProcessRequest(slug, method, body, headers);
|
|
2413
2533
|
const res = await dispatch(req);
|
|
@@ -2442,7 +2562,8 @@ var Functions = class _Functions {
|
|
|
2442
2562
|
if (error instanceof Error && error.name === "AbortError") {
|
|
2443
2563
|
throw error;
|
|
2444
2564
|
}
|
|
2445
|
-
|
|
2565
|
+
const unreachable = error instanceof ResultError && (error.statusCode === 404 || error.statusCode === 0);
|
|
2566
|
+
if (unreachable) {
|
|
2446
2567
|
} else {
|
|
2447
2568
|
return {
|
|
2448
2569
|
data: null,
|
|
@@ -2478,6 +2599,17 @@ var Functions = class _Functions {
|
|
|
2478
2599
|
// src/modules/realtime.ts
|
|
2479
2600
|
var CONNECT_TIMEOUT = 1e4;
|
|
2480
2601
|
var SUBSCRIBE_TIMEOUT = 1e4;
|
|
2602
|
+
var CHANNEL_PREFIX = "realtime:";
|
|
2603
|
+
function normalizeChannelMeta(message) {
|
|
2604
|
+
const channel = message?.meta?.channel;
|
|
2605
|
+
if (typeof channel !== "string" || !channel.startsWith(CHANNEL_PREFIX)) {
|
|
2606
|
+
return message;
|
|
2607
|
+
}
|
|
2608
|
+
return {
|
|
2609
|
+
...message,
|
|
2610
|
+
meta: { ...message.meta, channel: channel.slice(CHANNEL_PREFIX.length) }
|
|
2611
|
+
};
|
|
2612
|
+
}
|
|
2481
2613
|
var Realtime = class {
|
|
2482
2614
|
constructor(baseUrl, tokenManager, anonKey, getValidAccessToken = async () => tokenManager.getAccessToken()) {
|
|
2483
2615
|
this.baseUrl = baseUrl;
|
|
@@ -2599,8 +2731,9 @@ var Realtime = class {
|
|
|
2599
2731
|
if (event === "realtime:error") {
|
|
2600
2732
|
return;
|
|
2601
2733
|
}
|
|
2602
|
-
|
|
2603
|
-
this.
|
|
2734
|
+
const normalized = normalizeChannelMeta(message);
|
|
2735
|
+
this.applyPresenceEvent(event, normalized);
|
|
2736
|
+
this.notifyListeners(event, normalized);
|
|
2604
2737
|
};
|
|
2605
2738
|
this.connectionAttempt = { id: attemptId, socket, cancel: fail };
|
|
2606
2739
|
socket.on("connect", onConnect);
|
|
@@ -2848,6 +2981,17 @@ var Realtime = class {
|
|
|
2848
2981
|
this.socket.emit("realtime:unsubscribe", { channel });
|
|
2849
2982
|
}
|
|
2850
2983
|
}
|
|
2984
|
+
/**
|
|
2985
|
+
* Publish an event to a channel.
|
|
2986
|
+
*
|
|
2987
|
+
* Delivery notes (verified against a live backend):
|
|
2988
|
+
* - Payload fields arrive spread onto the received message itself, next to
|
|
2989
|
+
* `meta` - not nested under a `payload` key. Publishing `{ text: "hi" }`
|
|
2990
|
+
* means receivers read `msg.text`.
|
|
2991
|
+
* - The sender receives its own message too. Deduplicate with
|
|
2992
|
+
* `msg.meta.messageId` (or `msg.meta.senderId`) if you also update local
|
|
2993
|
+
* state optimistically.
|
|
2994
|
+
*/
|
|
2851
2995
|
async publish(channel, event, payload) {
|
|
2852
2996
|
if (!this.socket?.connected) {
|
|
2853
2997
|
throw new Error(
|
|
@@ -2856,6 +3000,12 @@ var Realtime = class {
|
|
|
2856
3000
|
}
|
|
2857
3001
|
this.socket.emit("realtime:publish", { channel, event, payload });
|
|
2858
3002
|
}
|
|
3003
|
+
/**
|
|
3004
|
+
* Listen for an event by name, across all subscribed channels.
|
|
3005
|
+
* Filter by channel inside the callback: `msg.meta.channel` always matches
|
|
3006
|
+
* the exact name passed to subscribe() (the SDK strips the server's
|
|
3007
|
+
* transport prefix before delivery).
|
|
3008
|
+
*/
|
|
2859
3009
|
on(event, callback) {
|
|
2860
3010
|
const listeners = this.eventListeners.get(event) ?? /* @__PURE__ */ new Set();
|
|
2861
3011
|
listeners.add(callback);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ResultConfig, o as ResultError } from './types-
|
|
1
|
+
import { a as ResultConfig, o as ResultError } from './types-BmU3deRO.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-BmU3deRO.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-VCWoai4o.cjs';
|
|
2
|
+
import '../types-BmU3deRO.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-Uh09_lFn.js';
|
|
2
|
+
import '../types-BmU3deRO.js';
|