@ragable/sdk 0.7.8 → 0.7.10
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 +180 -4
- package/dist/index.d.ts +180 -4
- package/dist/index.js +216 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +212 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2335,6 +2335,95 @@ 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
|
+
|
|
2338
2427
|
// src/stream-parts.ts
|
|
2339
2428
|
function normalizeFinishReason(raw) {
|
|
2340
2429
|
switch (raw) {
|
|
@@ -2547,7 +2636,9 @@ var ZERO_USAGE = {
|
|
|
2547
2636
|
function buildInferenceRequestBody(params, responseFormat) {
|
|
2548
2637
|
const body = {
|
|
2549
2638
|
model: params.model,
|
|
2550
|
-
messages: params.messages
|
|
2639
|
+
messages: params.messages.map(
|
|
2640
|
+
(m) => m.role === "user" ? { role: "user", content: toWireUserContent(m.content) } : m
|
|
2641
|
+
)
|
|
2551
2642
|
};
|
|
2552
2643
|
if (params.system !== void 0) body.system = params.system;
|
|
2553
2644
|
if (typeof params.temperature === "number")
|
|
@@ -3782,6 +3873,120 @@ var RagableBrowserStorageClient = class {
|
|
|
3782
3873
|
return new BrowserStorageBucketClient(this.options, this.fetchImpl, bucketId);
|
|
3783
3874
|
}
|
|
3784
3875
|
};
|
|
3876
|
+
var RagableBrowserMailClient = class {
|
|
3877
|
+
constructor(options, auth) {
|
|
3878
|
+
this.options = options;
|
|
3879
|
+
this.auth = auth;
|
|
3880
|
+
__publicField(this, "fetchImpl");
|
|
3881
|
+
this.fetchImpl = bindFetch(options.fetch);
|
|
3882
|
+
}
|
|
3883
|
+
requireWebsiteId() {
|
|
3884
|
+
const websiteId = this.options.websiteId?.trim();
|
|
3885
|
+
if (!websiteId) {
|
|
3886
|
+
throw new RagableError(
|
|
3887
|
+
"websiteId is required for mail operations. Use createWebsiteRagableClient() or pass createBrowserClient({ websiteId, ... }).",
|
|
3888
|
+
400,
|
|
3889
|
+
{ code: "SDK_MISSING_WEBSITE_ID" }
|
|
3890
|
+
);
|
|
3891
|
+
}
|
|
3892
|
+
return websiteId;
|
|
3893
|
+
}
|
|
3894
|
+
pathTo(p) {
|
|
3895
|
+
const websiteId = this.requireWebsiteId();
|
|
3896
|
+
const orgId = this.options.organizationId;
|
|
3897
|
+
return `${normalizeBrowserApiBase()}/public/organizations/${orgId}/websites/${websiteId}/mail${p.startsWith("/") ? p : `/${p}`}`;
|
|
3898
|
+
}
|
|
3899
|
+
/**
|
|
3900
|
+
* Get the Bearer token used to authenticate the call:
|
|
3901
|
+
* 1. End-user access token (preferred when an auth group is configured
|
|
3902
|
+
* and the user has signed in)
|
|
3903
|
+
* 2. `dataStaticKey` from createBrowserClient options
|
|
3904
|
+
* 3. Caller-supplied `getAccessToken()`
|
|
3905
|
+
*
|
|
3906
|
+
* If none is available, throws — server-side use should pass the
|
|
3907
|
+
* data-admin key as `dataStaticKey`.
|
|
3908
|
+
*/
|
|
3909
|
+
async getBearerToken() {
|
|
3910
|
+
if (this.auth) {
|
|
3911
|
+
const token = await this.auth.getValidAccessToken().catch(() => null);
|
|
3912
|
+
if (token) return token;
|
|
3913
|
+
}
|
|
3914
|
+
const callerProvided = await this.options.getAccessToken?.();
|
|
3915
|
+
if (typeof callerProvided === "string" && callerProvided.length > 0) {
|
|
3916
|
+
return callerProvided;
|
|
3917
|
+
}
|
|
3918
|
+
if (this.options.dataStaticKey?.trim()) {
|
|
3919
|
+
return this.options.dataStaticKey.trim();
|
|
3920
|
+
}
|
|
3921
|
+
throw new RagableError(
|
|
3922
|
+
"Mail requests need authentication: either sign in via client.auth.signIn(...) or pass dataStaticKey (the auth group data-admin key) when creating the client.",
|
|
3923
|
+
401,
|
|
3924
|
+
{ code: "SDK_MAIL_NOT_AUTHENTICATED" }
|
|
3925
|
+
);
|
|
3926
|
+
}
|
|
3927
|
+
async request(path, init = {}) {
|
|
3928
|
+
const token = await this.getBearerToken();
|
|
3929
|
+
const headers = new Headers(init.headers ?? this.options.headers);
|
|
3930
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
3931
|
+
if (init.body && !headers.has("Content-Type")) {
|
|
3932
|
+
headers.set("Content-Type", "application/json");
|
|
3933
|
+
}
|
|
3934
|
+
const response = await this.fetchImpl(this.pathTo(path), {
|
|
3935
|
+
...init,
|
|
3936
|
+
headers
|
|
3937
|
+
});
|
|
3938
|
+
const payload = await parseMaybeJsonBody(response);
|
|
3939
|
+
if (!response.ok) {
|
|
3940
|
+
const message = extractErrorMessage(payload, response.statusText);
|
|
3941
|
+
throw new RagableError(message, response.status, payload);
|
|
3942
|
+
}
|
|
3943
|
+
return payload;
|
|
3944
|
+
}
|
|
3945
|
+
/** Send an email from this website's linked Gmail account. */
|
|
3946
|
+
async send(params) {
|
|
3947
|
+
if (!params.to?.length) {
|
|
3948
|
+
throw new RagableError(
|
|
3949
|
+
"`to` must contain at least one recipient.",
|
|
3950
|
+
400,
|
|
3951
|
+
{ code: "SDK_MAIL_NO_RECIPIENTS" }
|
|
3952
|
+
);
|
|
3953
|
+
}
|
|
3954
|
+
if (!params.bodyText && !params.bodyHtml) {
|
|
3955
|
+
throw new RagableError(
|
|
3956
|
+
"Provide at least one of `bodyText` or `bodyHtml`.",
|
|
3957
|
+
400,
|
|
3958
|
+
{ code: "SDK_MAIL_NO_BODY" }
|
|
3959
|
+
);
|
|
3960
|
+
}
|
|
3961
|
+
return this.request("/send", {
|
|
3962
|
+
method: "POST",
|
|
3963
|
+
body: JSON.stringify(params)
|
|
3964
|
+
});
|
|
3965
|
+
}
|
|
3966
|
+
/** Search messages with Gmail query syntax. */
|
|
3967
|
+
async search(params = {}) {
|
|
3968
|
+
const qs = new URLSearchParams();
|
|
3969
|
+
if (params.query) qs.set("q", params.query);
|
|
3970
|
+
if (params.maxResults) qs.set("maxResults", String(params.maxResults));
|
|
3971
|
+
if (params.pageToken) qs.set("pageToken", params.pageToken);
|
|
3972
|
+
if (params.labelIds?.length) qs.set("labelIds", params.labelIds.join(","));
|
|
3973
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
3974
|
+
return this.request(`/search${suffix}`, { method: "GET" });
|
|
3975
|
+
}
|
|
3976
|
+
/** Fetch a single message in full (headers + decoded text/html body). */
|
|
3977
|
+
async getMessage(messageId) {
|
|
3978
|
+
if (!messageId) {
|
|
3979
|
+
throw new RagableError("`messageId` is required.", 400, {
|
|
3980
|
+
code: "SDK_MAIL_NO_MESSAGE_ID"
|
|
3981
|
+
});
|
|
3982
|
+
}
|
|
3983
|
+
const { message } = await this.request(
|
|
3984
|
+
`/messages/${encodeURIComponent(messageId)}`,
|
|
3985
|
+
{ method: "GET" }
|
|
3986
|
+
);
|
|
3987
|
+
return message;
|
|
3988
|
+
}
|
|
3989
|
+
};
|
|
3785
3990
|
var RagableBrowserAgentsClient = class {
|
|
3786
3991
|
constructor(options) {
|
|
3787
3992
|
this.options = options;
|
|
@@ -4108,6 +4313,7 @@ var RagableBrowser = class {
|
|
|
4108
4313
|
__publicField(this, "database");
|
|
4109
4314
|
__publicField(this, "db");
|
|
4110
4315
|
__publicField(this, "storage");
|
|
4316
|
+
__publicField(this, "mail");
|
|
4111
4317
|
__publicField(this, "transport");
|
|
4112
4318
|
__publicField(this, "_ragableAuth");
|
|
4113
4319
|
/** Delegates to `database.from()`. Kept for back-compat — prefer `database.from()`. */
|
|
@@ -4153,6 +4359,7 @@ var RagableBrowser = class {
|
|
|
4153
4359
|
this.database._setTransport(this.transport);
|
|
4154
4360
|
this.db = this.database;
|
|
4155
4361
|
this.storage = new RagableBrowserStorageClient(options, bindFetch(options.fetch));
|
|
4362
|
+
this.mail = new RagableBrowserMailClient(options, this._ragableAuth);
|
|
4156
4363
|
}
|
|
4157
4364
|
destroy() {
|
|
4158
4365
|
this._ragableAuth?.destroy();
|
|
@@ -4193,6 +4400,7 @@ export {
|
|
|
4193
4400
|
RagableBrowserAiClient,
|
|
4194
4401
|
RagableBrowserAuthClient,
|
|
4195
4402
|
RagableBrowserDatabaseClient,
|
|
4403
|
+
RagableBrowserMailClient,
|
|
4196
4404
|
RagableBrowserStorageClient,
|
|
4197
4405
|
RagableError,
|
|
4198
4406
|
RagableNetworkError,
|
|
@@ -4205,6 +4413,7 @@ export {
|
|
|
4205
4413
|
bindFetch,
|
|
4206
4414
|
buildInferenceRequestBody,
|
|
4207
4415
|
buildResponseFormat,
|
|
4416
|
+
bytesToBase64,
|
|
4208
4417
|
collectAssistantTextFromUiSegments,
|
|
4209
4418
|
collectionRecordToRowWithMeta,
|
|
4210
4419
|
collectionRecordsToRowWithMeta,
|
|
@@ -4220,6 +4429,7 @@ export {
|
|
|
4220
4429
|
formatPostgrestError,
|
|
4221
4430
|
formatSdkError,
|
|
4222
4431
|
generateIdempotencyKey,
|
|
4432
|
+
imagePartToUrl,
|
|
4223
4433
|
isIncompleteAgentStreamError,
|
|
4224
4434
|
mapAgentEvent,
|
|
4225
4435
|
mapFireworksChunk,
|
|
@@ -4234,6 +4444,7 @@ export {
|
|
|
4234
4444
|
runAgentChatStreamLenient,
|
|
4235
4445
|
streamObjectFromContext,
|
|
4236
4446
|
toRagableResult,
|
|
4447
|
+
toWireUserContent,
|
|
4237
4448
|
tryParsePartialJson,
|
|
4238
4449
|
unwrapPostgrest,
|
|
4239
4450
|
wrapStreamTextAsObject
|