@ragable/sdk 0.7.10 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +131 -89
- package/dist/index.d.ts +131 -89
- package/dist/index.js +105 -98
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +104 -95
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2335,95 +2335,6 @@ function stripTrailingCommas(text) {
|
|
|
2335
2335
|
return text.replace(/,(\s*[}\]])/g, "$1").replace(/,\s*$/, "");
|
|
2336
2336
|
}
|
|
2337
2337
|
|
|
2338
|
-
// src/content.ts
|
|
2339
|
-
var MAX_IMAGE_BYTES = 5 * 1024 * 1024;
|
|
2340
|
-
function toWireUserContent(content) {
|
|
2341
|
-
if (typeof content === "string") return content;
|
|
2342
|
-
const out = [];
|
|
2343
|
-
for (const part of content) {
|
|
2344
|
-
if (!part) continue;
|
|
2345
|
-
if (part.type === "text") {
|
|
2346
|
-
out.push(toWireTextPart(part));
|
|
2347
|
-
} else if (part.type === "image") {
|
|
2348
|
-
out.push(toWireImagePart(part));
|
|
2349
|
-
}
|
|
2350
|
-
}
|
|
2351
|
-
return out;
|
|
2352
|
-
}
|
|
2353
|
-
function toWireTextPart(part) {
|
|
2354
|
-
return { type: "text", text: part.text };
|
|
2355
|
-
}
|
|
2356
|
-
function toWireImagePart(part) {
|
|
2357
|
-
const url = imagePartToUrl(part);
|
|
2358
|
-
const detail = part.detail;
|
|
2359
|
-
return {
|
|
2360
|
-
type: "image_url",
|
|
2361
|
-
image_url: detail ? { url, detail } : { url }
|
|
2362
|
-
};
|
|
2363
|
-
}
|
|
2364
|
-
function imagePartToUrl(part) {
|
|
2365
|
-
const img = part.image;
|
|
2366
|
-
if (img instanceof URL) return img.href;
|
|
2367
|
-
if (typeof img === "string") {
|
|
2368
|
-
if (img.startsWith("http://") || img.startsWith("https://")) return img;
|
|
2369
|
-
if (img.startsWith("data:")) return img;
|
|
2370
|
-
const mediaType = requireMediaType(part, "raw base64 string");
|
|
2371
|
-
assertBase64SizeOk(img);
|
|
2372
|
-
return `data:${mediaType};base64,${img}`;
|
|
2373
|
-
}
|
|
2374
|
-
if (img instanceof Uint8Array || img instanceof ArrayBuffer) {
|
|
2375
|
-
const bytes = img instanceof Uint8Array ? img : new Uint8Array(img);
|
|
2376
|
-
assertBinarySizeOk(bytes);
|
|
2377
|
-
const mediaType = requireMediaType(part, "binary image data");
|
|
2378
|
-
const b64 = bytesToBase64(bytes);
|
|
2379
|
-
return `data:${mediaType};base64,${b64}`;
|
|
2380
|
-
}
|
|
2381
|
-
throw new RagableError(
|
|
2382
|
-
"ImagePart.image must be a string, URL, Uint8Array, or ArrayBuffer",
|
|
2383
|
-
400,
|
|
2384
|
-
{ code: "SDK_INVALID_IMAGE_PART" }
|
|
2385
|
-
);
|
|
2386
|
-
}
|
|
2387
|
-
function requireMediaType(part, what) {
|
|
2388
|
-
const m = part.mediaType?.trim();
|
|
2389
|
-
if (!m) {
|
|
2390
|
-
throw new RagableError(
|
|
2391
|
-
`ImagePart.mediaType is required for ${what} (e.g. "image/png")`,
|
|
2392
|
-
400,
|
|
2393
|
-
{ code: "SDK_IMAGE_MEDIA_TYPE_REQUIRED" }
|
|
2394
|
-
);
|
|
2395
|
-
}
|
|
2396
|
-
return m;
|
|
2397
|
-
}
|
|
2398
|
-
function assertBinarySizeOk(bytes) {
|
|
2399
|
-
if (bytes.byteLength > MAX_IMAGE_BYTES) {
|
|
2400
|
-
throw new RagableError(
|
|
2401
|
-
`Image exceeds 5MB limit (${bytes.byteLength} bytes)`,
|
|
2402
|
-
400,
|
|
2403
|
-
{ code: "SDK_IMAGE_TOO_LARGE" }
|
|
2404
|
-
);
|
|
2405
|
-
}
|
|
2406
|
-
}
|
|
2407
|
-
function assertBase64SizeOk(b64) {
|
|
2408
|
-
const approxBytes = Math.floor(b64.length * 3 / 4);
|
|
2409
|
-
if (approxBytes > MAX_IMAGE_BYTES) {
|
|
2410
|
-
throw new RagableError(
|
|
2411
|
-
`Image exceeds 5MB limit (~${approxBytes} bytes decoded)`,
|
|
2412
|
-
400,
|
|
2413
|
-
{ code: "SDK_IMAGE_TOO_LARGE" }
|
|
2414
|
-
);
|
|
2415
|
-
}
|
|
2416
|
-
}
|
|
2417
|
-
function bytesToBase64(bytes) {
|
|
2418
|
-
const CHUNK = 32768;
|
|
2419
|
-
let binary = "";
|
|
2420
|
-
for (let i = 0; i < bytes.length; i += CHUNK) {
|
|
2421
|
-
const slice = bytes.subarray(i, i + CHUNK);
|
|
2422
|
-
binary += String.fromCharCode(...slice);
|
|
2423
|
-
}
|
|
2424
|
-
return btoa(binary);
|
|
2425
|
-
}
|
|
2426
|
-
|
|
2427
2338
|
// src/stream-parts.ts
|
|
2428
2339
|
function normalizeFinishReason(raw) {
|
|
2429
2340
|
switch (raw) {
|
|
@@ -2636,9 +2547,7 @@ var ZERO_USAGE = {
|
|
|
2636
2547
|
function buildInferenceRequestBody(params, responseFormat) {
|
|
2637
2548
|
const body = {
|
|
2638
2549
|
model: params.model,
|
|
2639
|
-
messages: params.messages
|
|
2640
|
-
(m) => m.role === "user" ? { role: "user", content: toWireUserContent(m.content) } : m
|
|
2641
|
-
)
|
|
2550
|
+
messages: params.messages
|
|
2642
2551
|
};
|
|
2643
2552
|
if (params.system !== void 0) body.system = params.system;
|
|
2644
2553
|
if (typeof params.temperature === "number")
|
|
@@ -3987,6 +3896,99 @@ var RagableBrowserMailClient = class {
|
|
|
3987
3896
|
return message;
|
|
3988
3897
|
}
|
|
3989
3898
|
};
|
|
3899
|
+
var RagableBrowserFunctionsClient = class {
|
|
3900
|
+
constructor(options, auth) {
|
|
3901
|
+
this.options = options;
|
|
3902
|
+
this.auth = auth;
|
|
3903
|
+
__publicField(this, "fetchImpl");
|
|
3904
|
+
this.fetchImpl = bindFetch(options.fetch);
|
|
3905
|
+
}
|
|
3906
|
+
requireWebsiteId() {
|
|
3907
|
+
const websiteId = this.options.websiteId?.trim();
|
|
3908
|
+
if (!websiteId) {
|
|
3909
|
+
throw new RagableError(
|
|
3910
|
+
"websiteId is required for functions. Use createWebsiteRagableClient()/createAppClient() or pass createBrowserClient({ websiteId, ... }).",
|
|
3911
|
+
400,
|
|
3912
|
+
{ code: "SDK_MISSING_WEBSITE_ID" }
|
|
3913
|
+
);
|
|
3914
|
+
}
|
|
3915
|
+
return websiteId;
|
|
3916
|
+
}
|
|
3917
|
+
toUrl(name) {
|
|
3918
|
+
const orgId = this.options.organizationId;
|
|
3919
|
+
const websiteId = this.requireWebsiteId();
|
|
3920
|
+
return `${normalizeBrowserApiBase()}/public/organizations/${orgId}/websites/${websiteId}/functions/${encodeURIComponent(
|
|
3921
|
+
name
|
|
3922
|
+
)}/invoke`;
|
|
3923
|
+
}
|
|
3924
|
+
/**
|
|
3925
|
+
* Best-effort end-user bearer, forwarded to the function as `context.auth.token`.
|
|
3926
|
+
* Functions are public, so this never throws — anonymous calls send no token.
|
|
3927
|
+
*/
|
|
3928
|
+
async getOptionalToken() {
|
|
3929
|
+
if (this.auth) {
|
|
3930
|
+
const token = await this.auth.getValidAccessToken().catch(() => null);
|
|
3931
|
+
if (token) return token;
|
|
3932
|
+
}
|
|
3933
|
+
const caller = await Promise.resolve(this.options.getAccessToken?.()).catch(
|
|
3934
|
+
() => null
|
|
3935
|
+
);
|
|
3936
|
+
if (typeof caller === "string" && caller.trim()) return caller.trim();
|
|
3937
|
+
const staticKey = this.options.dataStaticKey?.trim();
|
|
3938
|
+
if (staticKey) return staticKey;
|
|
3939
|
+
return null;
|
|
3940
|
+
}
|
|
3941
|
+
/**
|
|
3942
|
+
* Invoke a function by name. Prefer the typed `client.functions.<name>(input)`
|
|
3943
|
+
* accessors; use this when the name is dynamic.
|
|
3944
|
+
*/
|
|
3945
|
+
async invoke(name, input, options) {
|
|
3946
|
+
const fnName = String(name ?? "").trim();
|
|
3947
|
+
if (!fnName) {
|
|
3948
|
+
throw new RagableError(
|
|
3949
|
+
"functions.invoke requires a function name",
|
|
3950
|
+
400,
|
|
3951
|
+
{ code: "SDK_MISSING_FUNCTION_NAME" }
|
|
3952
|
+
);
|
|
3953
|
+
}
|
|
3954
|
+
const headers = new Headers(options?.headers ?? this.options.headers);
|
|
3955
|
+
headers.set("Content-Type", "application/json");
|
|
3956
|
+
const token = await this.getOptionalToken();
|
|
3957
|
+
if (token) headers.set("Authorization", `Bearer ${token}`);
|
|
3958
|
+
const response = await this.fetchImpl(this.toUrl(fnName), {
|
|
3959
|
+
method: "POST",
|
|
3960
|
+
headers,
|
|
3961
|
+
body: JSON.stringify({ input: input ?? null }),
|
|
3962
|
+
...options?.signal ? { signal: options.signal } : {}
|
|
3963
|
+
});
|
|
3964
|
+
const payload = await parseMaybeJsonBody(response);
|
|
3965
|
+
if (!response.ok) {
|
|
3966
|
+
const message = extractErrorMessage(payload, response.statusText);
|
|
3967
|
+
throw new RagableError(message, response.status, payload);
|
|
3968
|
+
}
|
|
3969
|
+
if (payload && typeof payload === "object" && !Array.isArray(payload) && "result" in payload) {
|
|
3970
|
+
return payload.result;
|
|
3971
|
+
}
|
|
3972
|
+
return payload;
|
|
3973
|
+
}
|
|
3974
|
+
/** Build the typed Proxy exposed as `client.functions`. */
|
|
3975
|
+
asInvoker() {
|
|
3976
|
+
const invoke = this.invoke.bind(this);
|
|
3977
|
+
return new Proxy(
|
|
3978
|
+
{},
|
|
3979
|
+
{
|
|
3980
|
+
get: (_target, prop) => {
|
|
3981
|
+
if (typeof prop !== "string") return void 0;
|
|
3982
|
+
if (prop === "then") return void 0;
|
|
3983
|
+
if (prop === "invoke") {
|
|
3984
|
+
return (name, input, options) => invoke(name, input, options);
|
|
3985
|
+
}
|
|
3986
|
+
return (input, options) => invoke(prop, input, options);
|
|
3987
|
+
}
|
|
3988
|
+
}
|
|
3989
|
+
);
|
|
3990
|
+
}
|
|
3991
|
+
};
|
|
3990
3992
|
var RagableBrowserAgentsClient = class {
|
|
3991
3993
|
constructor(options) {
|
|
3992
3994
|
this.options = options;
|
|
@@ -4314,6 +4316,11 @@ var RagableBrowser = class {
|
|
|
4314
4316
|
__publicField(this, "db");
|
|
4315
4317
|
__publicField(this, "storage");
|
|
4316
4318
|
__publicField(this, "mail");
|
|
4319
|
+
/**
|
|
4320
|
+
* Backend edge functions — call a `/functions/<name>.ts` handler with
|
|
4321
|
+
* `client.functions.<name>(input)`. Runs server-side. See {@link FunctionInvoker}.
|
|
4322
|
+
*/
|
|
4323
|
+
__publicField(this, "functions");
|
|
4317
4324
|
__publicField(this, "transport");
|
|
4318
4325
|
__publicField(this, "_ragableAuth");
|
|
4319
4326
|
/** Delegates to `database.from()`. Kept for back-compat — prefer `database.from()`. */
|
|
@@ -4360,6 +4367,10 @@ var RagableBrowser = class {
|
|
|
4360
4367
|
this.db = this.database;
|
|
4361
4368
|
this.storage = new RagableBrowserStorageClient(options, bindFetch(options.fetch));
|
|
4362
4369
|
this.mail = new RagableBrowserMailClient(options, this._ragableAuth);
|
|
4370
|
+
this.functions = new RagableBrowserFunctionsClient(
|
|
4371
|
+
options,
|
|
4372
|
+
this._ragableAuth
|
|
4373
|
+
).asInvoker();
|
|
4363
4374
|
}
|
|
4364
4375
|
destroy() {
|
|
4365
4376
|
this._ragableAuth?.destroy();
|
|
@@ -4400,6 +4411,7 @@ export {
|
|
|
4400
4411
|
RagableBrowserAiClient,
|
|
4401
4412
|
RagableBrowserAuthClient,
|
|
4402
4413
|
RagableBrowserDatabaseClient,
|
|
4414
|
+
RagableBrowserFunctionsClient,
|
|
4403
4415
|
RagableBrowserMailClient,
|
|
4404
4416
|
RagableBrowserStorageClient,
|
|
4405
4417
|
RagableError,
|
|
@@ -4413,7 +4425,6 @@ export {
|
|
|
4413
4425
|
bindFetch,
|
|
4414
4426
|
buildInferenceRequestBody,
|
|
4415
4427
|
buildResponseFormat,
|
|
4416
|
-
bytesToBase64,
|
|
4417
4428
|
collectAssistantTextFromUiSegments,
|
|
4418
4429
|
collectionRecordToRowWithMeta,
|
|
4419
4430
|
collectionRecordsToRowWithMeta,
|
|
@@ -4429,7 +4440,6 @@ export {
|
|
|
4429
4440
|
formatPostgrestError,
|
|
4430
4441
|
formatSdkError,
|
|
4431
4442
|
generateIdempotencyKey,
|
|
4432
|
-
imagePartToUrl,
|
|
4433
4443
|
isIncompleteAgentStreamError,
|
|
4434
4444
|
mapAgentEvent,
|
|
4435
4445
|
mapFireworksChunk,
|
|
@@ -4444,7 +4454,6 @@ export {
|
|
|
4444
4454
|
runAgentChatStreamLenient,
|
|
4445
4455
|
streamObjectFromContext,
|
|
4446
4456
|
toRagableResult,
|
|
4447
|
-
toWireUserContent,
|
|
4448
4457
|
tryParsePartialJson,
|
|
4449
4458
|
unwrapPostgrest,
|
|
4450
4459
|
wrapStreamTextAsObject
|