@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.js
CHANGED
|
@@ -47,6 +47,7 @@ __export(index_exports, {
|
|
|
47
47
|
RagableBrowserAiClient: () => RagableBrowserAiClient,
|
|
48
48
|
RagableBrowserAuthClient: () => RagableBrowserAuthClient,
|
|
49
49
|
RagableBrowserDatabaseClient: () => RagableBrowserDatabaseClient,
|
|
50
|
+
RagableBrowserMailClient: () => RagableBrowserMailClient,
|
|
50
51
|
RagableBrowserStorageClient: () => RagableBrowserStorageClient,
|
|
51
52
|
RagableError: () => RagableError,
|
|
52
53
|
RagableNetworkError: () => RagableNetworkError,
|
|
@@ -59,6 +60,7 @@ __export(index_exports, {
|
|
|
59
60
|
bindFetch: () => bindFetch,
|
|
60
61
|
buildInferenceRequestBody: () => buildInferenceRequestBody,
|
|
61
62
|
buildResponseFormat: () => buildResponseFormat,
|
|
63
|
+
bytesToBase64: () => bytesToBase64,
|
|
62
64
|
collectAssistantTextFromUiSegments: () => collectAssistantTextFromUiSegments,
|
|
63
65
|
collectionRecordToRowWithMeta: () => collectionRecordToRowWithMeta,
|
|
64
66
|
collectionRecordsToRowWithMeta: () => collectionRecordsToRowWithMeta,
|
|
@@ -74,6 +76,7 @@ __export(index_exports, {
|
|
|
74
76
|
formatPostgrestError: () => formatPostgrestError,
|
|
75
77
|
formatSdkError: () => formatSdkError,
|
|
76
78
|
generateIdempotencyKey: () => generateIdempotencyKey,
|
|
79
|
+
imagePartToUrl: () => imagePartToUrl,
|
|
77
80
|
isIncompleteAgentStreamError: () => isIncompleteAgentStreamError,
|
|
78
81
|
mapAgentEvent: () => mapAgentEvent,
|
|
79
82
|
mapFireworksChunk: () => mapFireworksChunk,
|
|
@@ -88,6 +91,7 @@ __export(index_exports, {
|
|
|
88
91
|
runAgentChatStreamLenient: () => runAgentChatStreamLenient,
|
|
89
92
|
streamObjectFromContext: () => streamObjectFromContext,
|
|
90
93
|
toRagableResult: () => toRagableResult,
|
|
94
|
+
toWireUserContent: () => toWireUserContent,
|
|
91
95
|
tryParsePartialJson: () => tryParsePartialJson,
|
|
92
96
|
unwrapPostgrest: () => unwrapPostgrest,
|
|
93
97
|
wrapStreamTextAsObject: () => wrapStreamTextAsObject
|
|
@@ -2427,6 +2431,95 @@ function stripTrailingCommas(text) {
|
|
|
2427
2431
|
return text.replace(/,(\s*[}\]])/g, "$1").replace(/,\s*$/, "");
|
|
2428
2432
|
}
|
|
2429
2433
|
|
|
2434
|
+
// src/content.ts
|
|
2435
|
+
var MAX_IMAGE_BYTES = 5 * 1024 * 1024;
|
|
2436
|
+
function toWireUserContent(content) {
|
|
2437
|
+
if (typeof content === "string") return content;
|
|
2438
|
+
const out = [];
|
|
2439
|
+
for (const part of content) {
|
|
2440
|
+
if (!part) continue;
|
|
2441
|
+
if (part.type === "text") {
|
|
2442
|
+
out.push(toWireTextPart(part));
|
|
2443
|
+
} else if (part.type === "image") {
|
|
2444
|
+
out.push(toWireImagePart(part));
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
2447
|
+
return out;
|
|
2448
|
+
}
|
|
2449
|
+
function toWireTextPart(part) {
|
|
2450
|
+
return { type: "text", text: part.text };
|
|
2451
|
+
}
|
|
2452
|
+
function toWireImagePart(part) {
|
|
2453
|
+
const url = imagePartToUrl(part);
|
|
2454
|
+
const detail = part.detail;
|
|
2455
|
+
return {
|
|
2456
|
+
type: "image_url",
|
|
2457
|
+
image_url: detail ? { url, detail } : { url }
|
|
2458
|
+
};
|
|
2459
|
+
}
|
|
2460
|
+
function imagePartToUrl(part) {
|
|
2461
|
+
const img = part.image;
|
|
2462
|
+
if (img instanceof URL) return img.href;
|
|
2463
|
+
if (typeof img === "string") {
|
|
2464
|
+
if (img.startsWith("http://") || img.startsWith("https://")) return img;
|
|
2465
|
+
if (img.startsWith("data:")) return img;
|
|
2466
|
+
const mediaType = requireMediaType(part, "raw base64 string");
|
|
2467
|
+
assertBase64SizeOk(img);
|
|
2468
|
+
return `data:${mediaType};base64,${img}`;
|
|
2469
|
+
}
|
|
2470
|
+
if (img instanceof Uint8Array || img instanceof ArrayBuffer) {
|
|
2471
|
+
const bytes = img instanceof Uint8Array ? img : new Uint8Array(img);
|
|
2472
|
+
assertBinarySizeOk(bytes);
|
|
2473
|
+
const mediaType = requireMediaType(part, "binary image data");
|
|
2474
|
+
const b64 = bytesToBase64(bytes);
|
|
2475
|
+
return `data:${mediaType};base64,${b64}`;
|
|
2476
|
+
}
|
|
2477
|
+
throw new RagableError(
|
|
2478
|
+
"ImagePart.image must be a string, URL, Uint8Array, or ArrayBuffer",
|
|
2479
|
+
400,
|
|
2480
|
+
{ code: "SDK_INVALID_IMAGE_PART" }
|
|
2481
|
+
);
|
|
2482
|
+
}
|
|
2483
|
+
function requireMediaType(part, what) {
|
|
2484
|
+
const m = part.mediaType?.trim();
|
|
2485
|
+
if (!m) {
|
|
2486
|
+
throw new RagableError(
|
|
2487
|
+
`ImagePart.mediaType is required for ${what} (e.g. "image/png")`,
|
|
2488
|
+
400,
|
|
2489
|
+
{ code: "SDK_IMAGE_MEDIA_TYPE_REQUIRED" }
|
|
2490
|
+
);
|
|
2491
|
+
}
|
|
2492
|
+
return m;
|
|
2493
|
+
}
|
|
2494
|
+
function assertBinarySizeOk(bytes) {
|
|
2495
|
+
if (bytes.byteLength > MAX_IMAGE_BYTES) {
|
|
2496
|
+
throw new RagableError(
|
|
2497
|
+
`Image exceeds 5MB limit (${bytes.byteLength} bytes)`,
|
|
2498
|
+
400,
|
|
2499
|
+
{ code: "SDK_IMAGE_TOO_LARGE" }
|
|
2500
|
+
);
|
|
2501
|
+
}
|
|
2502
|
+
}
|
|
2503
|
+
function assertBase64SizeOk(b64) {
|
|
2504
|
+
const approxBytes = Math.floor(b64.length * 3 / 4);
|
|
2505
|
+
if (approxBytes > MAX_IMAGE_BYTES) {
|
|
2506
|
+
throw new RagableError(
|
|
2507
|
+
`Image exceeds 5MB limit (~${approxBytes} bytes decoded)`,
|
|
2508
|
+
400,
|
|
2509
|
+
{ code: "SDK_IMAGE_TOO_LARGE" }
|
|
2510
|
+
);
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
function bytesToBase64(bytes) {
|
|
2514
|
+
const CHUNK = 32768;
|
|
2515
|
+
let binary = "";
|
|
2516
|
+
for (let i = 0; i < bytes.length; i += CHUNK) {
|
|
2517
|
+
const slice = bytes.subarray(i, i + CHUNK);
|
|
2518
|
+
binary += String.fromCharCode(...slice);
|
|
2519
|
+
}
|
|
2520
|
+
return btoa(binary);
|
|
2521
|
+
}
|
|
2522
|
+
|
|
2430
2523
|
// src/stream-parts.ts
|
|
2431
2524
|
function normalizeFinishReason(raw) {
|
|
2432
2525
|
switch (raw) {
|
|
@@ -2639,7 +2732,9 @@ var ZERO_USAGE = {
|
|
|
2639
2732
|
function buildInferenceRequestBody(params, responseFormat) {
|
|
2640
2733
|
const body = {
|
|
2641
2734
|
model: params.model,
|
|
2642
|
-
messages: params.messages
|
|
2735
|
+
messages: params.messages.map(
|
|
2736
|
+
(m) => m.role === "user" ? { role: "user", content: toWireUserContent(m.content) } : m
|
|
2737
|
+
)
|
|
2643
2738
|
};
|
|
2644
2739
|
if (params.system !== void 0) body.system = params.system;
|
|
2645
2740
|
if (typeof params.temperature === "number")
|
|
@@ -3874,6 +3969,120 @@ var RagableBrowserStorageClient = class {
|
|
|
3874
3969
|
return new BrowserStorageBucketClient(this.options, this.fetchImpl, bucketId);
|
|
3875
3970
|
}
|
|
3876
3971
|
};
|
|
3972
|
+
var RagableBrowserMailClient = class {
|
|
3973
|
+
constructor(options, auth) {
|
|
3974
|
+
this.options = options;
|
|
3975
|
+
this.auth = auth;
|
|
3976
|
+
__publicField(this, "fetchImpl");
|
|
3977
|
+
this.fetchImpl = bindFetch(options.fetch);
|
|
3978
|
+
}
|
|
3979
|
+
requireWebsiteId() {
|
|
3980
|
+
const websiteId = this.options.websiteId?.trim();
|
|
3981
|
+
if (!websiteId) {
|
|
3982
|
+
throw new RagableError(
|
|
3983
|
+
"websiteId is required for mail operations. Use createWebsiteRagableClient() or pass createBrowserClient({ websiteId, ... }).",
|
|
3984
|
+
400,
|
|
3985
|
+
{ code: "SDK_MISSING_WEBSITE_ID" }
|
|
3986
|
+
);
|
|
3987
|
+
}
|
|
3988
|
+
return websiteId;
|
|
3989
|
+
}
|
|
3990
|
+
pathTo(p) {
|
|
3991
|
+
const websiteId = this.requireWebsiteId();
|
|
3992
|
+
const orgId = this.options.organizationId;
|
|
3993
|
+
return `${normalizeBrowserApiBase()}/public/organizations/${orgId}/websites/${websiteId}/mail${p.startsWith("/") ? p : `/${p}`}`;
|
|
3994
|
+
}
|
|
3995
|
+
/**
|
|
3996
|
+
* Get the Bearer token used to authenticate the call:
|
|
3997
|
+
* 1. End-user access token (preferred when an auth group is configured
|
|
3998
|
+
* and the user has signed in)
|
|
3999
|
+
* 2. `dataStaticKey` from createBrowserClient options
|
|
4000
|
+
* 3. Caller-supplied `getAccessToken()`
|
|
4001
|
+
*
|
|
4002
|
+
* If none is available, throws — server-side use should pass the
|
|
4003
|
+
* data-admin key as `dataStaticKey`.
|
|
4004
|
+
*/
|
|
4005
|
+
async getBearerToken() {
|
|
4006
|
+
if (this.auth) {
|
|
4007
|
+
const token = await this.auth.getValidAccessToken().catch(() => null);
|
|
4008
|
+
if (token) return token;
|
|
4009
|
+
}
|
|
4010
|
+
const callerProvided = await this.options.getAccessToken?.();
|
|
4011
|
+
if (typeof callerProvided === "string" && callerProvided.length > 0) {
|
|
4012
|
+
return callerProvided;
|
|
4013
|
+
}
|
|
4014
|
+
if (this.options.dataStaticKey?.trim()) {
|
|
4015
|
+
return this.options.dataStaticKey.trim();
|
|
4016
|
+
}
|
|
4017
|
+
throw new RagableError(
|
|
4018
|
+
"Mail requests need authentication: either sign in via client.auth.signIn(...) or pass dataStaticKey (the auth group data-admin key) when creating the client.",
|
|
4019
|
+
401,
|
|
4020
|
+
{ code: "SDK_MAIL_NOT_AUTHENTICATED" }
|
|
4021
|
+
);
|
|
4022
|
+
}
|
|
4023
|
+
async request(path, init = {}) {
|
|
4024
|
+
const token = await this.getBearerToken();
|
|
4025
|
+
const headers = new Headers(init.headers ?? this.options.headers);
|
|
4026
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
4027
|
+
if (init.body && !headers.has("Content-Type")) {
|
|
4028
|
+
headers.set("Content-Type", "application/json");
|
|
4029
|
+
}
|
|
4030
|
+
const response = await this.fetchImpl(this.pathTo(path), {
|
|
4031
|
+
...init,
|
|
4032
|
+
headers
|
|
4033
|
+
});
|
|
4034
|
+
const payload = await parseMaybeJsonBody(response);
|
|
4035
|
+
if (!response.ok) {
|
|
4036
|
+
const message = extractErrorMessage(payload, response.statusText);
|
|
4037
|
+
throw new RagableError(message, response.status, payload);
|
|
4038
|
+
}
|
|
4039
|
+
return payload;
|
|
4040
|
+
}
|
|
4041
|
+
/** Send an email from this website's linked Gmail account. */
|
|
4042
|
+
async send(params) {
|
|
4043
|
+
if (!params.to?.length) {
|
|
4044
|
+
throw new RagableError(
|
|
4045
|
+
"`to` must contain at least one recipient.",
|
|
4046
|
+
400,
|
|
4047
|
+
{ code: "SDK_MAIL_NO_RECIPIENTS" }
|
|
4048
|
+
);
|
|
4049
|
+
}
|
|
4050
|
+
if (!params.bodyText && !params.bodyHtml) {
|
|
4051
|
+
throw new RagableError(
|
|
4052
|
+
"Provide at least one of `bodyText` or `bodyHtml`.",
|
|
4053
|
+
400,
|
|
4054
|
+
{ code: "SDK_MAIL_NO_BODY" }
|
|
4055
|
+
);
|
|
4056
|
+
}
|
|
4057
|
+
return this.request("/send", {
|
|
4058
|
+
method: "POST",
|
|
4059
|
+
body: JSON.stringify(params)
|
|
4060
|
+
});
|
|
4061
|
+
}
|
|
4062
|
+
/** Search messages with Gmail query syntax. */
|
|
4063
|
+
async search(params = {}) {
|
|
4064
|
+
const qs = new URLSearchParams();
|
|
4065
|
+
if (params.query) qs.set("q", params.query);
|
|
4066
|
+
if (params.maxResults) qs.set("maxResults", String(params.maxResults));
|
|
4067
|
+
if (params.pageToken) qs.set("pageToken", params.pageToken);
|
|
4068
|
+
if (params.labelIds?.length) qs.set("labelIds", params.labelIds.join(","));
|
|
4069
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
4070
|
+
return this.request(`/search${suffix}`, { method: "GET" });
|
|
4071
|
+
}
|
|
4072
|
+
/** Fetch a single message in full (headers + decoded text/html body). */
|
|
4073
|
+
async getMessage(messageId) {
|
|
4074
|
+
if (!messageId) {
|
|
4075
|
+
throw new RagableError("`messageId` is required.", 400, {
|
|
4076
|
+
code: "SDK_MAIL_NO_MESSAGE_ID"
|
|
4077
|
+
});
|
|
4078
|
+
}
|
|
4079
|
+
const { message } = await this.request(
|
|
4080
|
+
`/messages/${encodeURIComponent(messageId)}`,
|
|
4081
|
+
{ method: "GET" }
|
|
4082
|
+
);
|
|
4083
|
+
return message;
|
|
4084
|
+
}
|
|
4085
|
+
};
|
|
3877
4086
|
var RagableBrowserAgentsClient = class {
|
|
3878
4087
|
constructor(options) {
|
|
3879
4088
|
this.options = options;
|
|
@@ -4200,6 +4409,7 @@ var RagableBrowser = class {
|
|
|
4200
4409
|
__publicField(this, "database");
|
|
4201
4410
|
__publicField(this, "db");
|
|
4202
4411
|
__publicField(this, "storage");
|
|
4412
|
+
__publicField(this, "mail");
|
|
4203
4413
|
__publicField(this, "transport");
|
|
4204
4414
|
__publicField(this, "_ragableAuth");
|
|
4205
4415
|
/** Delegates to `database.from()`. Kept for back-compat — prefer `database.from()`. */
|
|
@@ -4245,6 +4455,7 @@ var RagableBrowser = class {
|
|
|
4245
4455
|
this.database._setTransport(this.transport);
|
|
4246
4456
|
this.db = this.database;
|
|
4247
4457
|
this.storage = new RagableBrowserStorageClient(options, bindFetch(options.fetch));
|
|
4458
|
+
this.mail = new RagableBrowserMailClient(options, this._ragableAuth);
|
|
4248
4459
|
}
|
|
4249
4460
|
destroy() {
|
|
4250
4461
|
this._ragableAuth?.destroy();
|
|
@@ -4286,6 +4497,7 @@ function createClient(options) {
|
|
|
4286
4497
|
RagableBrowserAiClient,
|
|
4287
4498
|
RagableBrowserAuthClient,
|
|
4288
4499
|
RagableBrowserDatabaseClient,
|
|
4500
|
+
RagableBrowserMailClient,
|
|
4289
4501
|
RagableBrowserStorageClient,
|
|
4290
4502
|
RagableError,
|
|
4291
4503
|
RagableNetworkError,
|
|
@@ -4298,6 +4510,7 @@ function createClient(options) {
|
|
|
4298
4510
|
bindFetch,
|
|
4299
4511
|
buildInferenceRequestBody,
|
|
4300
4512
|
buildResponseFormat,
|
|
4513
|
+
bytesToBase64,
|
|
4301
4514
|
collectAssistantTextFromUiSegments,
|
|
4302
4515
|
collectionRecordToRowWithMeta,
|
|
4303
4516
|
collectionRecordsToRowWithMeta,
|
|
@@ -4313,6 +4526,7 @@ function createClient(options) {
|
|
|
4313
4526
|
formatPostgrestError,
|
|
4314
4527
|
formatSdkError,
|
|
4315
4528
|
generateIdempotencyKey,
|
|
4529
|
+
imagePartToUrl,
|
|
4316
4530
|
isIncompleteAgentStreamError,
|
|
4317
4531
|
mapAgentEvent,
|
|
4318
4532
|
mapFireworksChunk,
|
|
@@ -4327,6 +4541,7 @@ function createClient(options) {
|
|
|
4327
4541
|
runAgentChatStreamLenient,
|
|
4328
4542
|
streamObjectFromContext,
|
|
4329
4543
|
toRagableResult,
|
|
4544
|
+
toWireUserContent,
|
|
4330
4545
|
tryParsePartialJson,
|
|
4331
4546
|
unwrapPostgrest,
|
|
4332
4547
|
wrapStreamTextAsObject
|