@resultdev/sdk 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/dist/{client-Z0zUHGE3.d.ts → client-CJv_awPt.d.cts} +60 -30
- package/dist/{client-DeE086La.d.cts → client-DrsZ1qIm.d.ts} +60 -30
- package/dist/index.cjs +161 -19
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +161 -19
- package/dist/{middleware-TGaDOhE9.d.ts → middleware-BJl9JRg3.d.ts} +1 -1
- package/dist/{middleware-BBY_6hyx.d.cts → middleware-C1Z6aMvn.d.cts} +1 -1
- package/dist/ssr/middleware.d.cts +2 -2
- package/dist/ssr/middleware.d.ts +2 -2
- package/dist/ssr.cjs +161 -19
- package/dist/ssr.d.cts +4 -4
- package/dist/ssr.d.ts +4 -4
- package/dist/ssr.js +161 -19
- package/dist/{types-CbsaMttt.d.cts → types-DSVtGaIA.d.cts} +9 -1
- package/dist/{types-CbsaMttt.d.ts → types-DSVtGaIA.d.ts} +9 -1
- package/package.json +1 -1
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-DrsZ1qIm.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-DrsZ1qIm.js';
|
|
3
|
+
import { R as ResultAdminConfig, a as ResultConfig } from './types-DSVtGaIA.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-DSVtGaIA.js';
|
|
5
5
|
import '@supabase/postgrest-js';
|
|
6
6
|
|
|
7
7
|
/**
|
package/dist/index.js
CHANGED
|
@@ -966,6 +966,70 @@ var HttpClient = class {
|
|
|
966
966
|
};
|
|
967
967
|
|
|
968
968
|
// src/modules/ai.ts
|
|
969
|
+
var SUPPORTED_AUDIO_FORMATS = [
|
|
970
|
+
"wav",
|
|
971
|
+
"mp3",
|
|
972
|
+
"aiff",
|
|
973
|
+
"aac",
|
|
974
|
+
"ogg",
|
|
975
|
+
"flac",
|
|
976
|
+
"m4a"
|
|
977
|
+
];
|
|
978
|
+
var MULTIMODAL_MODEL = "google/gemini-2.5-flash";
|
|
979
|
+
function summarizeContent(messages) {
|
|
980
|
+
const summary = {
|
|
981
|
+
hasImage: false,
|
|
982
|
+
hasAudio: false,
|
|
983
|
+
badAudioFormats: []
|
|
984
|
+
};
|
|
985
|
+
for (const message of messages) {
|
|
986
|
+
if (message.images?.length) {
|
|
987
|
+
summary.hasImage = true;
|
|
988
|
+
}
|
|
989
|
+
if (!Array.isArray(message.content)) {
|
|
990
|
+
continue;
|
|
991
|
+
}
|
|
992
|
+
for (const part of message.content) {
|
|
993
|
+
if (part?.type === "image_url") {
|
|
994
|
+
summary.hasImage = true;
|
|
995
|
+
} else if (part?.type === "input_audio") {
|
|
996
|
+
summary.hasAudio = true;
|
|
997
|
+
const format2 = part.input_audio?.format;
|
|
998
|
+
if (format2 && !SUPPORTED_AUDIO_FORMATS.includes(format2)) {
|
|
999
|
+
summary.badAudioFormats.push(format2);
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
return summary;
|
|
1005
|
+
}
|
|
1006
|
+
function assertSupportedContent(model, summary) {
|
|
1007
|
+
if (summary.badAudioFormats.length) {
|
|
1008
|
+
throw new ResultError(
|
|
1009
|
+
`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.`,
|
|
1010
|
+
400,
|
|
1011
|
+
"AI_INVALID_INPUT"
|
|
1012
|
+
);
|
|
1013
|
+
}
|
|
1014
|
+
if (summary.hasAudio && model.startsWith("openai/")) {
|
|
1015
|
+
throw new ResultError(
|
|
1016
|
+
`Model "${model}" does not accept audio input on this gateway. Use ${MULTIMODAL_MODEL} (verified for audio).`,
|
|
1017
|
+
400,
|
|
1018
|
+
"AI_INVALID_INPUT"
|
|
1019
|
+
);
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
function enrichUpstreamError(error, summary) {
|
|
1023
|
+
if (!(error instanceof ResultError) || error.error !== "AI_UPSTREAM_UNAVAILABLE" || !summary.hasImage && !summary.hasAudio) {
|
|
1024
|
+
return error;
|
|
1025
|
+
}
|
|
1026
|
+
const kind = summary.hasImage && summary.hasAudio ? "image and audio" : summary.hasImage ? "image" : "audio";
|
|
1027
|
+
return new ResultError(
|
|
1028
|
+
`${error.message} This request included ${kind} input; if the error persists, use ${MULTIMODAL_MODEL} (verified for vision and audio).`,
|
|
1029
|
+
error.statusCode,
|
|
1030
|
+
error.error
|
|
1031
|
+
);
|
|
1032
|
+
}
|
|
969
1033
|
var AI = class {
|
|
970
1034
|
chat;
|
|
971
1035
|
images;
|
|
@@ -988,6 +1052,8 @@ var ChatCompletions = class {
|
|
|
988
1052
|
}
|
|
989
1053
|
http;
|
|
990
1054
|
async create(params) {
|
|
1055
|
+
const contentSummary = summarizeContent(params.messages ?? []);
|
|
1056
|
+
assertSupportedContent(params.model, contentSummary);
|
|
991
1057
|
const backendParams = {
|
|
992
1058
|
model: params.model,
|
|
993
1059
|
messages: params.messages,
|
|
@@ -1016,15 +1082,28 @@ var ChatCompletions = class {
|
|
|
1016
1082
|
}
|
|
1017
1083
|
);
|
|
1018
1084
|
if (!response2.ok) {
|
|
1019
|
-
|
|
1020
|
-
|
|
1085
|
+
let body = null;
|
|
1086
|
+
try {
|
|
1087
|
+
body = await response2.json();
|
|
1088
|
+
} catch {
|
|
1089
|
+
}
|
|
1090
|
+
throw enrichUpstreamError(
|
|
1091
|
+
new ResultError(
|
|
1092
|
+
body?.message || body?.error || "Stream request failed",
|
|
1093
|
+
body?.statusCode ?? response2.status,
|
|
1094
|
+
body?.error || "AI_STREAM_ERROR"
|
|
1095
|
+
),
|
|
1096
|
+
contentSummary
|
|
1097
|
+
);
|
|
1021
1098
|
}
|
|
1022
1099
|
return this.parseSSEStream(response2, params.model);
|
|
1023
1100
|
}
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
backendParams
|
|
1027
|
-
)
|
|
1101
|
+
let response;
|
|
1102
|
+
try {
|
|
1103
|
+
response = await this.http.post("/api/ai/chat/completion", backendParams);
|
|
1104
|
+
} catch (error) {
|
|
1105
|
+
throw enrichUpstreamError(error, contentSummary);
|
|
1106
|
+
}
|
|
1028
1107
|
const content = response.text || "";
|
|
1029
1108
|
return {
|
|
1030
1109
|
id: `chatcmpl-${Date.now()}`,
|
|
@@ -1119,6 +1198,37 @@ var ChatCompletions = class {
|
|
|
1119
1198
|
]
|
|
1120
1199
|
};
|
|
1121
1200
|
}
|
|
1201
|
+
if (data.annotations?.length) {
|
|
1202
|
+
yield {
|
|
1203
|
+
id: `chatcmpl-${Date.now()}`,
|
|
1204
|
+
object: "chat.completion.chunk",
|
|
1205
|
+
created: Math.floor(Date.now() / 1e3),
|
|
1206
|
+
model,
|
|
1207
|
+
choices: [
|
|
1208
|
+
{
|
|
1209
|
+
index: 0,
|
|
1210
|
+
delta: {
|
|
1211
|
+
annotations: data.annotations
|
|
1212
|
+
},
|
|
1213
|
+
finish_reason: null
|
|
1214
|
+
}
|
|
1215
|
+
]
|
|
1216
|
+
};
|
|
1217
|
+
}
|
|
1218
|
+
if (data.tokenUsage) {
|
|
1219
|
+
yield {
|
|
1220
|
+
id: `chatcmpl-${Date.now()}`,
|
|
1221
|
+
object: "chat.completion.chunk",
|
|
1222
|
+
created: Math.floor(Date.now() / 1e3),
|
|
1223
|
+
model,
|
|
1224
|
+
choices: [],
|
|
1225
|
+
usage: {
|
|
1226
|
+
prompt_tokens: data.tokenUsage.promptTokens || 0,
|
|
1227
|
+
completion_tokens: data.tokenUsage.completionTokens || 0,
|
|
1228
|
+
total_tokens: data.tokenUsage.totalTokens || 0
|
|
1229
|
+
}
|
|
1230
|
+
};
|
|
1231
|
+
}
|
|
1122
1232
|
if (data.done) {
|
|
1123
1233
|
reader.releaseLock();
|
|
1124
1234
|
return;
|
|
@@ -2355,13 +2465,13 @@ var Functions = class _Functions {
|
|
|
2355
2465
|
functionsUrl;
|
|
2356
2466
|
constructor(http, functionsUrl) {
|
|
2357
2467
|
this.http = http;
|
|
2358
|
-
this.functionsUrl = functionsUrl
|
|
2468
|
+
this.functionsUrl = functionsUrl;
|
|
2359
2469
|
}
|
|
2360
2470
|
/**
|
|
2361
|
-
* Derive the subhosting URL from the base URL
|
|
2362
|
-
* Rewrites the backend base URL to its functions subhosting URL
|
|
2471
|
+
* Derive the legacy subhosting URL from the base URL
|
|
2363
2472
|
* ({appKey}.{region}.<domain> -> {appKey}.functions.<domain>).
|
|
2364
|
-
* Only
|
|
2473
|
+
* Only used to recognize when a configured functionsUrl still points at
|
|
2474
|
+
* the local deployment, so in-process dispatch can short-circuit it.
|
|
2365
2475
|
*/
|
|
2366
2476
|
static deriveSubhostingUrl(baseUrl) {
|
|
2367
2477
|
try {
|
|
@@ -2394,11 +2504,13 @@ var Functions = class _Functions {
|
|
|
2394
2504
|
* Invoke an Edge Function.
|
|
2395
2505
|
*
|
|
2396
2506
|
* Dispatch order:
|
|
2397
|
-
* 1. If the platform's in-process dispatch hook is present
|
|
2398
|
-
*
|
|
2399
|
-
*
|
|
2400
|
-
* 2.
|
|
2401
|
-
*
|
|
2507
|
+
* 1. If the platform's in-process dispatch hook is present and no foreign
|
|
2508
|
+
* functionsUrl is configured, call it directly (function-to-function
|
|
2509
|
+
* calls inside the same deployment).
|
|
2510
|
+
* 2. If a custom functionsUrl is configured, try it; fall back to the
|
|
2511
|
+
* proxy path on 404 or network failure.
|
|
2512
|
+
* 3. Otherwise, invoke through the main host's /functions/{slug} proxy.
|
|
2513
|
+
* This route works from browsers too (correct CORS).
|
|
2402
2514
|
*
|
|
2403
2515
|
* @param slug The function slug to invoke
|
|
2404
2516
|
* @param options Request options
|
|
@@ -2407,7 +2519,7 @@ var Functions = class _Functions {
|
|
|
2407
2519
|
const { method = "POST", body, headers = {} } = options;
|
|
2408
2520
|
const dispatch = globalThis.__insforge_dispatch__;
|
|
2409
2521
|
const localFunctionsUrl = _Functions.deriveSubhostingUrl(this.http.baseUrl);
|
|
2410
|
-
if (typeof dispatch === "function" && !!localFunctionsUrl && this.functionsUrl === localFunctionsUrl) {
|
|
2522
|
+
if (typeof dispatch === "function" && (this.functionsUrl === void 0 || !!localFunctionsUrl && this.functionsUrl === localFunctionsUrl)) {
|
|
2411
2523
|
try {
|
|
2412
2524
|
const req = this.buildInProcessRequest(slug, method, body, headers);
|
|
2413
2525
|
const res = await dispatch(req);
|
|
@@ -2442,7 +2554,8 @@ var Functions = class _Functions {
|
|
|
2442
2554
|
if (error instanceof Error && error.name === "AbortError") {
|
|
2443
2555
|
throw error;
|
|
2444
2556
|
}
|
|
2445
|
-
|
|
2557
|
+
const unreachable = error instanceof ResultError && (error.statusCode === 404 || error.statusCode === 0);
|
|
2558
|
+
if (unreachable) {
|
|
2446
2559
|
} else {
|
|
2447
2560
|
return {
|
|
2448
2561
|
data: null,
|
|
@@ -2478,6 +2591,17 @@ var Functions = class _Functions {
|
|
|
2478
2591
|
// src/modules/realtime.ts
|
|
2479
2592
|
var CONNECT_TIMEOUT = 1e4;
|
|
2480
2593
|
var SUBSCRIBE_TIMEOUT = 1e4;
|
|
2594
|
+
var CHANNEL_PREFIX = "realtime:";
|
|
2595
|
+
function normalizeChannelMeta(message) {
|
|
2596
|
+
const channel = message?.meta?.channel;
|
|
2597
|
+
if (typeof channel !== "string" || !channel.startsWith(CHANNEL_PREFIX)) {
|
|
2598
|
+
return message;
|
|
2599
|
+
}
|
|
2600
|
+
return {
|
|
2601
|
+
...message,
|
|
2602
|
+
meta: { ...message.meta, channel: channel.slice(CHANNEL_PREFIX.length) }
|
|
2603
|
+
};
|
|
2604
|
+
}
|
|
2481
2605
|
var Realtime = class {
|
|
2482
2606
|
constructor(baseUrl, tokenManager, anonKey, getValidAccessToken = async () => tokenManager.getAccessToken()) {
|
|
2483
2607
|
this.baseUrl = baseUrl;
|
|
@@ -2599,8 +2723,9 @@ var Realtime = class {
|
|
|
2599
2723
|
if (event === "realtime:error") {
|
|
2600
2724
|
return;
|
|
2601
2725
|
}
|
|
2602
|
-
|
|
2603
|
-
this.
|
|
2726
|
+
const normalized = normalizeChannelMeta(message);
|
|
2727
|
+
this.applyPresenceEvent(event, normalized);
|
|
2728
|
+
this.notifyListeners(event, normalized);
|
|
2604
2729
|
};
|
|
2605
2730
|
this.connectionAttempt = { id: attemptId, socket, cancel: fail };
|
|
2606
2731
|
socket.on("connect", onConnect);
|
|
@@ -2848,6 +2973,17 @@ var Realtime = class {
|
|
|
2848
2973
|
this.socket.emit("realtime:unsubscribe", { channel });
|
|
2849
2974
|
}
|
|
2850
2975
|
}
|
|
2976
|
+
/**
|
|
2977
|
+
* Publish an event to a channel.
|
|
2978
|
+
*
|
|
2979
|
+
* Delivery notes (verified against a live backend):
|
|
2980
|
+
* - Payload fields arrive spread onto the received message itself, next to
|
|
2981
|
+
* `meta` - not nested under a `payload` key. Publishing `{ text: "hi" }`
|
|
2982
|
+
* means receivers read `msg.text`.
|
|
2983
|
+
* - The sender receives its own message too. Deduplicate with
|
|
2984
|
+
* `msg.meta.messageId` (or `msg.meta.senderId`) if you also update local
|
|
2985
|
+
* state optimistically.
|
|
2986
|
+
*/
|
|
2851
2987
|
async publish(channel, event, payload) {
|
|
2852
2988
|
if (!this.socket?.connected) {
|
|
2853
2989
|
throw new Error(
|
|
@@ -2856,6 +2992,12 @@ var Realtime = class {
|
|
|
2856
2992
|
}
|
|
2857
2993
|
this.socket.emit("realtime:publish", { channel, event, payload });
|
|
2858
2994
|
}
|
|
2995
|
+
/**
|
|
2996
|
+
* Listen for an event by name, across all subscribed channels.
|
|
2997
|
+
* Filter by channel inside the callback: `msg.meta.channel` always matches
|
|
2998
|
+
* the exact name passed to subscribe() (the SDK strips the server's
|
|
2999
|
+
* transport prefix before delivery).
|
|
3000
|
+
*/
|
|
2859
3001
|
on(event, callback) {
|
|
2860
3002
|
const listeners = this.eventListeners.get(event) ?? /* @__PURE__ */ new Set();
|
|
2861
3003
|
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-DSVtGaIA.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-DSVtGaIA.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-C1Z6aMvn.cjs';
|
|
2
|
+
import '../types-DSVtGaIA.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-BJl9JRg3.js';
|
|
2
|
+
import '../types-DSVtGaIA.js';
|
package/dist/ssr.cjs
CHANGED
|
@@ -1208,6 +1208,70 @@ var HttpClient = class {
|
|
|
1208
1208
|
};
|
|
1209
1209
|
|
|
1210
1210
|
// src/modules/ai.ts
|
|
1211
|
+
var SUPPORTED_AUDIO_FORMATS = [
|
|
1212
|
+
"wav",
|
|
1213
|
+
"mp3",
|
|
1214
|
+
"aiff",
|
|
1215
|
+
"aac",
|
|
1216
|
+
"ogg",
|
|
1217
|
+
"flac",
|
|
1218
|
+
"m4a"
|
|
1219
|
+
];
|
|
1220
|
+
var MULTIMODAL_MODEL = "google/gemini-2.5-flash";
|
|
1221
|
+
function summarizeContent(messages) {
|
|
1222
|
+
const summary = {
|
|
1223
|
+
hasImage: false,
|
|
1224
|
+
hasAudio: false,
|
|
1225
|
+
badAudioFormats: []
|
|
1226
|
+
};
|
|
1227
|
+
for (const message of messages) {
|
|
1228
|
+
if (message.images?.length) {
|
|
1229
|
+
summary.hasImage = true;
|
|
1230
|
+
}
|
|
1231
|
+
if (!Array.isArray(message.content)) {
|
|
1232
|
+
continue;
|
|
1233
|
+
}
|
|
1234
|
+
for (const part of message.content) {
|
|
1235
|
+
if (part?.type === "image_url") {
|
|
1236
|
+
summary.hasImage = true;
|
|
1237
|
+
} else if (part?.type === "input_audio") {
|
|
1238
|
+
summary.hasAudio = true;
|
|
1239
|
+
const format2 = part.input_audio?.format;
|
|
1240
|
+
if (format2 && !SUPPORTED_AUDIO_FORMATS.includes(format2)) {
|
|
1241
|
+
summary.badAudioFormats.push(format2);
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
return summary;
|
|
1247
|
+
}
|
|
1248
|
+
function assertSupportedContent(model, summary) {
|
|
1249
|
+
if (summary.badAudioFormats.length) {
|
|
1250
|
+
throw new ResultError(
|
|
1251
|
+
`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.`,
|
|
1252
|
+
400,
|
|
1253
|
+
"AI_INVALID_INPUT"
|
|
1254
|
+
);
|
|
1255
|
+
}
|
|
1256
|
+
if (summary.hasAudio && model.startsWith("openai/")) {
|
|
1257
|
+
throw new ResultError(
|
|
1258
|
+
`Model "${model}" does not accept audio input on this gateway. Use ${MULTIMODAL_MODEL} (verified for audio).`,
|
|
1259
|
+
400,
|
|
1260
|
+
"AI_INVALID_INPUT"
|
|
1261
|
+
);
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
function enrichUpstreamError(error, summary) {
|
|
1265
|
+
if (!(error instanceof ResultError) || error.error !== "AI_UPSTREAM_UNAVAILABLE" || !summary.hasImage && !summary.hasAudio) {
|
|
1266
|
+
return error;
|
|
1267
|
+
}
|
|
1268
|
+
const kind = summary.hasImage && summary.hasAudio ? "image and audio" : summary.hasImage ? "image" : "audio";
|
|
1269
|
+
return new ResultError(
|
|
1270
|
+
`${error.message} This request included ${kind} input; if the error persists, use ${MULTIMODAL_MODEL} (verified for vision and audio).`,
|
|
1271
|
+
error.statusCode,
|
|
1272
|
+
error.error
|
|
1273
|
+
);
|
|
1274
|
+
}
|
|
1211
1275
|
var AI = class {
|
|
1212
1276
|
chat;
|
|
1213
1277
|
images;
|
|
@@ -1230,6 +1294,8 @@ var ChatCompletions = class {
|
|
|
1230
1294
|
}
|
|
1231
1295
|
http;
|
|
1232
1296
|
async create(params) {
|
|
1297
|
+
const contentSummary = summarizeContent(params.messages ?? []);
|
|
1298
|
+
assertSupportedContent(params.model, contentSummary);
|
|
1233
1299
|
const backendParams = {
|
|
1234
1300
|
model: params.model,
|
|
1235
1301
|
messages: params.messages,
|
|
@@ -1258,15 +1324,28 @@ var ChatCompletions = class {
|
|
|
1258
1324
|
}
|
|
1259
1325
|
);
|
|
1260
1326
|
if (!response2.ok) {
|
|
1261
|
-
|
|
1262
|
-
|
|
1327
|
+
let body = null;
|
|
1328
|
+
try {
|
|
1329
|
+
body = await response2.json();
|
|
1330
|
+
} catch {
|
|
1331
|
+
}
|
|
1332
|
+
throw enrichUpstreamError(
|
|
1333
|
+
new ResultError(
|
|
1334
|
+
body?.message || body?.error || "Stream request failed",
|
|
1335
|
+
body?.statusCode ?? response2.status,
|
|
1336
|
+
body?.error || "AI_STREAM_ERROR"
|
|
1337
|
+
),
|
|
1338
|
+
contentSummary
|
|
1339
|
+
);
|
|
1263
1340
|
}
|
|
1264
1341
|
return this.parseSSEStream(response2, params.model);
|
|
1265
1342
|
}
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
backendParams
|
|
1269
|
-
)
|
|
1343
|
+
let response;
|
|
1344
|
+
try {
|
|
1345
|
+
response = await this.http.post("/api/ai/chat/completion", backendParams);
|
|
1346
|
+
} catch (error) {
|
|
1347
|
+
throw enrichUpstreamError(error, contentSummary);
|
|
1348
|
+
}
|
|
1270
1349
|
const content = response.text || "";
|
|
1271
1350
|
return {
|
|
1272
1351
|
id: `chatcmpl-${Date.now()}`,
|
|
@@ -1361,6 +1440,37 @@ var ChatCompletions = class {
|
|
|
1361
1440
|
]
|
|
1362
1441
|
};
|
|
1363
1442
|
}
|
|
1443
|
+
if (data.annotations?.length) {
|
|
1444
|
+
yield {
|
|
1445
|
+
id: `chatcmpl-${Date.now()}`,
|
|
1446
|
+
object: "chat.completion.chunk",
|
|
1447
|
+
created: Math.floor(Date.now() / 1e3),
|
|
1448
|
+
model,
|
|
1449
|
+
choices: [
|
|
1450
|
+
{
|
|
1451
|
+
index: 0,
|
|
1452
|
+
delta: {
|
|
1453
|
+
annotations: data.annotations
|
|
1454
|
+
},
|
|
1455
|
+
finish_reason: null
|
|
1456
|
+
}
|
|
1457
|
+
]
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1460
|
+
if (data.tokenUsage) {
|
|
1461
|
+
yield {
|
|
1462
|
+
id: `chatcmpl-${Date.now()}`,
|
|
1463
|
+
object: "chat.completion.chunk",
|
|
1464
|
+
created: Math.floor(Date.now() / 1e3),
|
|
1465
|
+
model,
|
|
1466
|
+
choices: [],
|
|
1467
|
+
usage: {
|
|
1468
|
+
prompt_tokens: data.tokenUsage.promptTokens || 0,
|
|
1469
|
+
completion_tokens: data.tokenUsage.completionTokens || 0,
|
|
1470
|
+
total_tokens: data.tokenUsage.totalTokens || 0
|
|
1471
|
+
}
|
|
1472
|
+
};
|
|
1473
|
+
}
|
|
1364
1474
|
if (data.done) {
|
|
1365
1475
|
reader.releaseLock();
|
|
1366
1476
|
return;
|
|
@@ -2597,13 +2707,13 @@ var Functions = class _Functions {
|
|
|
2597
2707
|
functionsUrl;
|
|
2598
2708
|
constructor(http, functionsUrl) {
|
|
2599
2709
|
this.http = http;
|
|
2600
|
-
this.functionsUrl = functionsUrl
|
|
2710
|
+
this.functionsUrl = functionsUrl;
|
|
2601
2711
|
}
|
|
2602
2712
|
/**
|
|
2603
|
-
* Derive the subhosting URL from the base URL
|
|
2604
|
-
* Rewrites the backend base URL to its functions subhosting URL
|
|
2713
|
+
* Derive the legacy subhosting URL from the base URL
|
|
2605
2714
|
* ({appKey}.{region}.<domain> -> {appKey}.functions.<domain>).
|
|
2606
|
-
* Only
|
|
2715
|
+
* Only used to recognize when a configured functionsUrl still points at
|
|
2716
|
+
* the local deployment, so in-process dispatch can short-circuit it.
|
|
2607
2717
|
*/
|
|
2608
2718
|
static deriveSubhostingUrl(baseUrl) {
|
|
2609
2719
|
try {
|
|
@@ -2636,11 +2746,13 @@ var Functions = class _Functions {
|
|
|
2636
2746
|
* Invoke an Edge Function.
|
|
2637
2747
|
*
|
|
2638
2748
|
* Dispatch order:
|
|
2639
|
-
* 1. If the platform's in-process dispatch hook is present
|
|
2640
|
-
*
|
|
2641
|
-
*
|
|
2642
|
-
* 2.
|
|
2643
|
-
*
|
|
2749
|
+
* 1. If the platform's in-process dispatch hook is present and no foreign
|
|
2750
|
+
* functionsUrl is configured, call it directly (function-to-function
|
|
2751
|
+
* calls inside the same deployment).
|
|
2752
|
+
* 2. If a custom functionsUrl is configured, try it; fall back to the
|
|
2753
|
+
* proxy path on 404 or network failure.
|
|
2754
|
+
* 3. Otherwise, invoke through the main host's /functions/{slug} proxy.
|
|
2755
|
+
* This route works from browsers too (correct CORS).
|
|
2644
2756
|
*
|
|
2645
2757
|
* @param slug The function slug to invoke
|
|
2646
2758
|
* @param options Request options
|
|
@@ -2649,7 +2761,7 @@ var Functions = class _Functions {
|
|
|
2649
2761
|
const { method = "POST", body, headers = {} } = options;
|
|
2650
2762
|
const dispatch = globalThis.__insforge_dispatch__;
|
|
2651
2763
|
const localFunctionsUrl = _Functions.deriveSubhostingUrl(this.http.baseUrl);
|
|
2652
|
-
if (typeof dispatch === "function" && !!localFunctionsUrl && this.functionsUrl === localFunctionsUrl) {
|
|
2764
|
+
if (typeof dispatch === "function" && (this.functionsUrl === void 0 || !!localFunctionsUrl && this.functionsUrl === localFunctionsUrl)) {
|
|
2653
2765
|
try {
|
|
2654
2766
|
const req = this.buildInProcessRequest(slug, method, body, headers);
|
|
2655
2767
|
const res = await dispatch(req);
|
|
@@ -2684,7 +2796,8 @@ var Functions = class _Functions {
|
|
|
2684
2796
|
if (error instanceof Error && error.name === "AbortError") {
|
|
2685
2797
|
throw error;
|
|
2686
2798
|
}
|
|
2687
|
-
|
|
2799
|
+
const unreachable = error instanceof ResultError && (error.statusCode === 404 || error.statusCode === 0);
|
|
2800
|
+
if (unreachable) {
|
|
2688
2801
|
} else {
|
|
2689
2802
|
return {
|
|
2690
2803
|
data: null,
|
|
@@ -2720,6 +2833,17 @@ var Functions = class _Functions {
|
|
|
2720
2833
|
// src/modules/realtime.ts
|
|
2721
2834
|
var CONNECT_TIMEOUT = 1e4;
|
|
2722
2835
|
var SUBSCRIBE_TIMEOUT = 1e4;
|
|
2836
|
+
var CHANNEL_PREFIX = "realtime:";
|
|
2837
|
+
function normalizeChannelMeta(message) {
|
|
2838
|
+
const channel = message?.meta?.channel;
|
|
2839
|
+
if (typeof channel !== "string" || !channel.startsWith(CHANNEL_PREFIX)) {
|
|
2840
|
+
return message;
|
|
2841
|
+
}
|
|
2842
|
+
return {
|
|
2843
|
+
...message,
|
|
2844
|
+
meta: { ...message.meta, channel: channel.slice(CHANNEL_PREFIX.length) }
|
|
2845
|
+
};
|
|
2846
|
+
}
|
|
2723
2847
|
var Realtime = class {
|
|
2724
2848
|
constructor(baseUrl, tokenManager, anonKey, getValidAccessToken = async () => tokenManager.getAccessToken()) {
|
|
2725
2849
|
this.baseUrl = baseUrl;
|
|
@@ -2841,8 +2965,9 @@ var Realtime = class {
|
|
|
2841
2965
|
if (event === "realtime:error") {
|
|
2842
2966
|
return;
|
|
2843
2967
|
}
|
|
2844
|
-
|
|
2845
|
-
this.
|
|
2968
|
+
const normalized = normalizeChannelMeta(message);
|
|
2969
|
+
this.applyPresenceEvent(event, normalized);
|
|
2970
|
+
this.notifyListeners(event, normalized);
|
|
2846
2971
|
};
|
|
2847
2972
|
this.connectionAttempt = { id: attemptId, socket, cancel: fail };
|
|
2848
2973
|
socket.on("connect", onConnect);
|
|
@@ -3090,6 +3215,17 @@ var Realtime = class {
|
|
|
3090
3215
|
this.socket.emit("realtime:unsubscribe", { channel });
|
|
3091
3216
|
}
|
|
3092
3217
|
}
|
|
3218
|
+
/**
|
|
3219
|
+
* Publish an event to a channel.
|
|
3220
|
+
*
|
|
3221
|
+
* Delivery notes (verified against a live backend):
|
|
3222
|
+
* - Payload fields arrive spread onto the received message itself, next to
|
|
3223
|
+
* `meta` - not nested under a `payload` key. Publishing `{ text: "hi" }`
|
|
3224
|
+
* means receivers read `msg.text`.
|
|
3225
|
+
* - The sender receives its own message too. Deduplicate with
|
|
3226
|
+
* `msg.meta.messageId` (or `msg.meta.senderId`) if you also update local
|
|
3227
|
+
* state optimistically.
|
|
3228
|
+
*/
|
|
3093
3229
|
async publish(channel, event, payload) {
|
|
3094
3230
|
if (!this.socket?.connected) {
|
|
3095
3231
|
throw new Error(
|
|
@@ -3098,6 +3234,12 @@ var Realtime = class {
|
|
|
3098
3234
|
}
|
|
3099
3235
|
this.socket.emit("realtime:publish", { channel, event, payload });
|
|
3100
3236
|
}
|
|
3237
|
+
/**
|
|
3238
|
+
* Listen for an event by name, across all subscribed channels.
|
|
3239
|
+
* Filter by channel inside the callback: `msg.meta.channel` always matches
|
|
3240
|
+
* the exact name passed to subscribe() (the SDK strips the server's
|
|
3241
|
+
* transport prefix before delivery).
|
|
3242
|
+
*/
|
|
3101
3243
|
on(event, callback) {
|
|
3102
3244
|
const listeners = this.eventListeners.get(event) ?? /* @__PURE__ */ new Set();
|
|
3103
3245
|
listeners.add(callback);
|
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-CJv_awPt.cjs';
|
|
2
|
+
import { o as ResultError, a as ResultConfig, G as AuthRefreshResponse } from './types-DSVtGaIA.cjs';
|
|
3
|
+
import { A as AuthCookieSettings, C as CookieStore, a as CookieWriter } from './middleware-C1Z6aMvn.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-C1Z6aMvn.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-DrsZ1qIm.js';
|
|
2
|
+
import { o as ResultError, a as ResultConfig, G as AuthRefreshResponse } from './types-DSVtGaIA.js';
|
|
3
|
+
import { A as AuthCookieSettings, C as CookieStore, a as CookieWriter } from './middleware-BJl9JRg3.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-BJl9JRg3.js';
|
|
5
5
|
import '@supabase/postgrest-js';
|
|
6
6
|
|
|
7
7
|
interface CreateAuthActionsOptions extends Omit<ResultConfig, "accessToken" | "edgeFunctionToken" | "isServerMode" | "auth">, AuthCookieSettings {
|