@ragable/sdk 0.7.7 → 0.7.9

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.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,
@@ -58,6 +59,7 @@ __export(index_exports, {
58
59
  assertPostgrestSuccess: () => assertPostgrestSuccess,
59
60
  bindFetch: () => bindFetch,
60
61
  buildInferenceRequestBody: () => buildInferenceRequestBody,
62
+ buildResponseFormat: () => buildResponseFormat,
61
63
  collectAssistantTextFromUiSegments: () => collectAssistantTextFromUiSegments,
62
64
  collectionRecordToRowWithMeta: () => collectionRecordToRowWithMeta,
63
65
  collectionRecordsToRowWithMeta: () => collectionRecordsToRowWithMeta,
@@ -85,8 +87,11 @@ __export(index_exports, {
85
87
  runAgentChatStream: () => runAgentChatStream,
86
88
  runAgentChatStreamForUi: () => runAgentChatStreamForUi,
87
89
  runAgentChatStreamLenient: () => runAgentChatStreamLenient,
90
+ streamObjectFromContext: () => streamObjectFromContext,
88
91
  toRagableResult: () => toRagableResult,
89
- unwrapPostgrest: () => unwrapPostgrest
92
+ tryParsePartialJson: () => tryParsePartialJson,
93
+ unwrapPostgrest: () => unwrapPostgrest,
94
+ wrapStreamTextAsObject: () => wrapStreamTextAsObject
90
95
  });
91
96
  module.exports = __toCommonJS(index_exports);
92
97
 
@@ -2357,6 +2362,72 @@ function decodeJwtExpiry(jwt) {
2357
2362
  }
2358
2363
  }
2359
2364
 
2365
+ // src/partial-json.ts
2366
+ function tryParsePartialJson(text) {
2367
+ const trimmed = text.trim();
2368
+ if (!trimmed) return void 0;
2369
+ try {
2370
+ return JSON.parse(trimmed);
2371
+ } catch {
2372
+ }
2373
+ const repaired = repairOpenStructures(trimmed);
2374
+ if (!repaired) return void 0;
2375
+ try {
2376
+ return JSON.parse(repaired);
2377
+ } catch {
2378
+ const noTrailingComma = stripTrailingCommas(trimmed);
2379
+ const repaired2 = repairOpenStructures(noTrailingComma);
2380
+ if (!repaired2) return void 0;
2381
+ try {
2382
+ return JSON.parse(repaired2);
2383
+ } catch {
2384
+ return void 0;
2385
+ }
2386
+ }
2387
+ }
2388
+ function repairOpenStructures(text) {
2389
+ const first = text[0];
2390
+ if (first !== "{" && first !== "[") {
2391
+ return text;
2392
+ }
2393
+ const stack = [];
2394
+ let inString = false;
2395
+ let escaped = false;
2396
+ for (let i = 0; i < text.length; i++) {
2397
+ const ch = text[i];
2398
+ if (escaped) {
2399
+ escaped = false;
2400
+ continue;
2401
+ }
2402
+ if (ch === "\\") {
2403
+ escaped = true;
2404
+ continue;
2405
+ }
2406
+ if (ch === '"') {
2407
+ inString = !inString;
2408
+ continue;
2409
+ }
2410
+ if (inString) continue;
2411
+ if (ch === "{") stack.push("}");
2412
+ else if (ch === "[") stack.push("]");
2413
+ else if (ch === "}" || ch === "]") {
2414
+ if (stack.length === 0) return null;
2415
+ stack.pop();
2416
+ }
2417
+ }
2418
+ let safe = text;
2419
+ if (inString) {
2420
+ safe += '"';
2421
+ }
2422
+ safe = safe.replace(/,\s*$/, "").replace(/:\s*$/, ": null");
2423
+ let suffix = "";
2424
+ for (let i = stack.length - 1; i >= 0; i--) suffix += stack[i];
2425
+ return safe + suffix;
2426
+ }
2427
+ function stripTrailingCommas(text) {
2428
+ return text.replace(/,(\s*[}\]])/g, "$1").replace(/,\s*$/, "");
2429
+ }
2430
+
2360
2431
  // src/stream-parts.ts
2361
2432
  function normalizeFinishReason(raw) {
2362
2433
  switch (raw) {
@@ -2566,7 +2637,7 @@ var ZERO_USAGE = {
2566
2637
  completionTokens: 0,
2567
2638
  totalTokens: 0
2568
2639
  };
2569
- function buildInferenceRequestBody(params) {
2640
+ function buildInferenceRequestBody(params, responseFormat) {
2570
2641
  const body = {
2571
2642
  model: params.model,
2572
2643
  messages: params.messages
@@ -2577,8 +2648,18 @@ function buildInferenceRequestBody(params) {
2577
2648
  if (typeof params.maxTokens === "number") body.max_tokens = params.maxTokens;
2578
2649
  if (typeof params.topP === "number") body.top_p = params.topP;
2579
2650
  if (params.reasoningEffort) body.reasoning_effort = params.reasoningEffort;
2651
+ if (responseFormat) body.response_format = responseFormat;
2580
2652
  return body;
2581
2653
  }
2654
+ function buildResponseFormat(params) {
2655
+ const json_schema = {
2656
+ name: params.name ?? "Output",
2657
+ schema: params.schema,
2658
+ strict: params.strict ?? true
2659
+ };
2660
+ if (params.description) json_schema.description = params.description;
2661
+ return { type: "json_schema", json_schema };
2662
+ }
2582
2663
  async function consumeInferenceStream(body, broadcast, deferreds) {
2583
2664
  const reader = body.getReader();
2584
2665
  const decoder = new TextDecoder();
@@ -2829,6 +2910,190 @@ var RagableBrowserAiClient = class {
2829
2910
  );
2830
2911
  return { text, reasoning, usage, finishReason, toolCalls };
2831
2912
  }
2913
+ /**
2914
+ * Stream a JSON-Schema-constrained response. Matches Vercel AI SDK's
2915
+ * `streamObject` shape — returns a synchronous result with `partialObjectStream`
2916
+ * (best-effort incremental parses) and `object` (the final parsed JSON).
2917
+ *
2918
+ * ```ts
2919
+ * const { partialObjectStream, object } = client.ai.streamObject({
2920
+ * model: "accounts/fireworks/models/kimi-k2p5",
2921
+ * schema: {
2922
+ * type: "object",
2923
+ * properties: {
2924
+ * title: { type: "string" },
2925
+ * tags: { type: "array", items: { type: "string" } },
2926
+ * },
2927
+ * required: ["title", "tags"],
2928
+ * },
2929
+ * messages: [{ role: "user", content: "Give me a blog post idea about AI." }],
2930
+ * });
2931
+ * for await (const partial of partialObjectStream) renderPreview(partial);
2932
+ * const final = await object;
2933
+ * ```
2934
+ */
2935
+ streamObject(params) {
2936
+ return streamObjectFromContext(this.buildContext(), params);
2937
+ }
2938
+ /**
2939
+ * Non-streaming variant of {@link streamObject}. Resolves once the model
2940
+ * finishes; rejects if the final text isn't valid JSON for the schema.
2941
+ */
2942
+ async generateObject(params) {
2943
+ const result = this.streamObject(params);
2944
+ for await (const _ of result.partialObjectStream) {
2945
+ void _;
2946
+ }
2947
+ const [object, usage, finishReason, toolCalls] = await Promise.all([
2948
+ result.object,
2949
+ result.usage,
2950
+ result.finishReason,
2951
+ result.toolCalls
2952
+ ]);
2953
+ return { object, usage, finishReason, toolCalls };
2954
+ }
2955
+ };
2956
+ function streamObjectFromContext(ctx, params) {
2957
+ const textParams = {
2958
+ model: params.model,
2959
+ messages: params.messages,
2960
+ ...params.system !== void 0 ? { system: params.system } : {},
2961
+ ...typeof params.temperature === "number" ? { temperature: params.temperature } : {},
2962
+ ...typeof params.maxTokens === "number" ? { maxTokens: params.maxTokens } : {},
2963
+ ...typeof params.topP === "number" ? { topP: params.topP } : {},
2964
+ ...params.signal !== void 0 ? { signal: params.signal } : {}
2965
+ };
2966
+ const responseFormat = buildResponseFormat({
2967
+ schema: params.schema,
2968
+ ...params.schemaName !== void 0 ? { name: params.schemaName } : {},
2969
+ ...params.schemaDescription !== void 0 ? { description: params.schemaDescription } : {}
2970
+ });
2971
+ const overrideCtx = {
2972
+ ...ctx,
2973
+ // Wrap fetch to substitute the body. We can't change buildInferenceRequestBody
2974
+ // signature on the call site cleanly, so intercept here.
2975
+ fetch: ((input, init) => {
2976
+ if (init && typeof init.body === "string") {
2977
+ const parsed = JSON.parse(init.body);
2978
+ parsed.response_format = responseFormat;
2979
+ const newInit = { ...init, body: JSON.stringify(parsed) };
2980
+ return ctx.fetch(input, newInit);
2981
+ }
2982
+ return ctx.fetch(input, init);
2983
+ })
2984
+ };
2985
+ const inner = streamInferenceFromContext(overrideCtx, textParams);
2986
+ return wrapStreamTextAsObject(inner);
2987
+ }
2988
+ function wrapStreamTextAsObject(inner) {
2989
+ const partialBroadcast = new PartialObjectBroadcast();
2990
+ const objectDeferred = defer();
2991
+ void (async () => {
2992
+ let acc = "";
2993
+ let lastEmitted = /* @__PURE__ */ Symbol("none");
2994
+ try {
2995
+ for await (const delta of inner.textStream) {
2996
+ acc += delta;
2997
+ const candidate = tryParsePartialJson(acc);
2998
+ if (candidate !== void 0 && !sameSnapshot(candidate, lastEmitted)) {
2999
+ lastEmitted = candidate;
3000
+ partialBroadcast.push(candidate);
3001
+ }
3002
+ }
3003
+ const finalText = await inner.text;
3004
+ let finalObj;
3005
+ try {
3006
+ finalObj = JSON.parse(finalText);
3007
+ } catch (e) {
3008
+ const err = new RagableError(
3009
+ `Model output is not valid JSON: ${e.message}`,
3010
+ 502,
3011
+ {
3012
+ code: "SDK_OBJECT_PARSE_FAILED",
3013
+ raw: finalText.slice(0, 1e3)
3014
+ }
3015
+ );
3016
+ partialBroadcast.fail(err);
3017
+ objectDeferred.reject(err);
3018
+ return;
3019
+ }
3020
+ if (!sameSnapshot(finalObj, lastEmitted)) {
3021
+ partialBroadcast.push(finalObj);
3022
+ }
3023
+ partialBroadcast.end();
3024
+ objectDeferred.resolve(finalObj);
3025
+ } catch (err) {
3026
+ partialBroadcast.fail(err);
3027
+ objectDeferred.reject(err);
3028
+ }
3029
+ })();
3030
+ return {
3031
+ textStream: inner.textStream,
3032
+ partialObjectStream: partialBroadcast.consume(),
3033
+ object: objectDeferred.promise,
3034
+ text: inner.text,
3035
+ usage: inner.usage,
3036
+ finishReason: inner.finishReason,
3037
+ toolCalls: inner.toolCalls
3038
+ };
3039
+ }
3040
+ function sameSnapshot(a, b) {
3041
+ if (a === b) return true;
3042
+ try {
3043
+ return JSON.stringify(a) === JSON.stringify(b);
3044
+ } catch {
3045
+ return false;
3046
+ }
3047
+ }
3048
+ var PartialObjectBroadcast = class {
3049
+ constructor() {
3050
+ __publicField(this, "items", []);
3051
+ __publicField(this, "resolved", false);
3052
+ __publicField(this, "error", null);
3053
+ __publicField(this, "waiters", []);
3054
+ }
3055
+ push(item) {
3056
+ this.items.push(item);
3057
+ this.notify();
3058
+ }
3059
+ end() {
3060
+ if (this.resolved) return;
3061
+ this.resolved = true;
3062
+ this.notify();
3063
+ }
3064
+ fail(error) {
3065
+ if (this.resolved) return;
3066
+ this.error = error;
3067
+ this.resolved = true;
3068
+ this.notify();
3069
+ }
3070
+ notify() {
3071
+ const w = this.waiters;
3072
+ this.waiters = [];
3073
+ for (const fn of w) fn();
3074
+ }
3075
+ consume() {
3076
+ const self = this;
3077
+ return {
3078
+ [Symbol.asyncIterator]: () => {
3079
+ let idx = 0;
3080
+ return {
3081
+ next: async () => {
3082
+ while (true) {
3083
+ if (idx < self.items.length) {
3084
+ return { value: self.items[idx++], done: false };
3085
+ }
3086
+ if (self.resolved) {
3087
+ if (self.error) throw self.error;
3088
+ return { value: void 0, done: true };
3089
+ }
3090
+ await new Promise((res) => self.waiters.push(res));
3091
+ }
3092
+ }
3093
+ };
3094
+ }
3095
+ };
3096
+ }
2832
3097
  };
2833
3098
 
2834
3099
  // src/browser.ts
@@ -3610,6 +3875,120 @@ var RagableBrowserStorageClient = class {
3610
3875
  return new BrowserStorageBucketClient(this.options, this.fetchImpl, bucketId);
3611
3876
  }
3612
3877
  };
3878
+ var RagableBrowserMailClient = class {
3879
+ constructor(options, auth) {
3880
+ this.options = options;
3881
+ this.auth = auth;
3882
+ __publicField(this, "fetchImpl");
3883
+ this.fetchImpl = bindFetch(options.fetch);
3884
+ }
3885
+ requireWebsiteId() {
3886
+ const websiteId = this.options.websiteId?.trim();
3887
+ if (!websiteId) {
3888
+ throw new RagableError(
3889
+ "websiteId is required for mail operations. Use createWebsiteRagableClient() or pass createBrowserClient({ websiteId, ... }).",
3890
+ 400,
3891
+ { code: "SDK_MISSING_WEBSITE_ID" }
3892
+ );
3893
+ }
3894
+ return websiteId;
3895
+ }
3896
+ pathTo(p) {
3897
+ const websiteId = this.requireWebsiteId();
3898
+ const orgId = this.options.organizationId;
3899
+ return `${normalizeBrowserApiBase()}/public/organizations/${orgId}/websites/${websiteId}/mail${p.startsWith("/") ? p : `/${p}`}`;
3900
+ }
3901
+ /**
3902
+ * Get the Bearer token used to authenticate the call:
3903
+ * 1. End-user access token (preferred when an auth group is configured
3904
+ * and the user has signed in)
3905
+ * 2. `dataStaticKey` from createBrowserClient options
3906
+ * 3. Caller-supplied `getAccessToken()`
3907
+ *
3908
+ * If none is available, throws — server-side use should pass the
3909
+ * data-admin key as `dataStaticKey`.
3910
+ */
3911
+ async getBearerToken() {
3912
+ if (this.auth) {
3913
+ const token = await this.auth.getValidAccessToken().catch(() => null);
3914
+ if (token) return token;
3915
+ }
3916
+ const callerProvided = await this.options.getAccessToken?.();
3917
+ if (typeof callerProvided === "string" && callerProvided.length > 0) {
3918
+ return callerProvided;
3919
+ }
3920
+ if (this.options.dataStaticKey?.trim()) {
3921
+ return this.options.dataStaticKey.trim();
3922
+ }
3923
+ throw new RagableError(
3924
+ "Mail requests need authentication: either sign in via client.auth.signIn(...) or pass dataStaticKey (the auth group data-admin key) when creating the client.",
3925
+ 401,
3926
+ { code: "SDK_MAIL_NOT_AUTHENTICATED" }
3927
+ );
3928
+ }
3929
+ async request(path, init = {}) {
3930
+ const token = await this.getBearerToken();
3931
+ const headers = new Headers(init.headers ?? this.options.headers);
3932
+ headers.set("Authorization", `Bearer ${token}`);
3933
+ if (init.body && !headers.has("Content-Type")) {
3934
+ headers.set("Content-Type", "application/json");
3935
+ }
3936
+ const response = await this.fetchImpl(this.pathTo(path), {
3937
+ ...init,
3938
+ headers
3939
+ });
3940
+ const payload = await parseMaybeJsonBody(response);
3941
+ if (!response.ok) {
3942
+ const message = extractErrorMessage(payload, response.statusText);
3943
+ throw new RagableError(message, response.status, payload);
3944
+ }
3945
+ return payload;
3946
+ }
3947
+ /** Send an email from this website's linked Gmail account. */
3948
+ async send(params) {
3949
+ if (!params.to?.length) {
3950
+ throw new RagableError(
3951
+ "`to` must contain at least one recipient.",
3952
+ 400,
3953
+ { code: "SDK_MAIL_NO_RECIPIENTS" }
3954
+ );
3955
+ }
3956
+ if (!params.bodyText && !params.bodyHtml) {
3957
+ throw new RagableError(
3958
+ "Provide at least one of `bodyText` or `bodyHtml`.",
3959
+ 400,
3960
+ { code: "SDK_MAIL_NO_BODY" }
3961
+ );
3962
+ }
3963
+ return this.request("/send", {
3964
+ method: "POST",
3965
+ body: JSON.stringify(params)
3966
+ });
3967
+ }
3968
+ /** Search messages with Gmail query syntax. */
3969
+ async search(params = {}) {
3970
+ const qs = new URLSearchParams();
3971
+ if (params.query) qs.set("q", params.query);
3972
+ if (params.maxResults) qs.set("maxResults", String(params.maxResults));
3973
+ if (params.pageToken) qs.set("pageToken", params.pageToken);
3974
+ if (params.labelIds?.length) qs.set("labelIds", params.labelIds.join(","));
3975
+ const suffix = qs.toString() ? `?${qs.toString()}` : "";
3976
+ return this.request(`/search${suffix}`, { method: "GET" });
3977
+ }
3978
+ /** Fetch a single message in full (headers + decoded text/html body). */
3979
+ async getMessage(messageId) {
3980
+ if (!messageId) {
3981
+ throw new RagableError("`messageId` is required.", 400, {
3982
+ code: "SDK_MAIL_NO_MESSAGE_ID"
3983
+ });
3984
+ }
3985
+ const { message } = await this.request(
3986
+ `/messages/${encodeURIComponent(messageId)}`,
3987
+ { method: "GET" }
3988
+ );
3989
+ return message;
3990
+ }
3991
+ };
3613
3992
  var RagableBrowserAgentsClient = class {
3614
3993
  constructor(options) {
3615
3994
  this.options = options;
@@ -3691,6 +4070,63 @@ var RagableBrowserAgentsClient = class {
3691
4070
  const source = this.runStreamParts(agentName, params);
3692
4071
  return createStreamResultFromParts(source);
3693
4072
  }
4073
+ /**
4074
+ * Same agent, same tools/instructions/RAG — but constrain the final output
4075
+ * to a JSON Schema. Matches `client.ai.streamObject` exactly so callers can
4076
+ * swap between raw inference and an agent without changing call shape.
4077
+ *
4078
+ * Tool calling and structured output are **compatible**: the model may call
4079
+ * the agent's tools as usual; the final assistant message is the schema-
4080
+ * conformant JSON. The agent's `agents/<name>.json` is unchanged — whether
4081
+ * the run is conversational or structured is decided by the call site.
4082
+ *
4083
+ * ```ts
4084
+ * const { partialObjectStream, object } = client.agents.runObject<Plan>(
4085
+ * "planner",
4086
+ * {
4087
+ * messages: [{ role: "user", content: "Plan a 3-day trip to Kyoto." }],
4088
+ * schema: {
4089
+ * type: "object",
4090
+ * properties: {
4091
+ * days: {
4092
+ * type: "array",
4093
+ * items: { type: "object", properties: { date: { type: "string" }, activities: { type: "array", items: { type: "string" } } } },
4094
+ * },
4095
+ * },
4096
+ * required: ["days"],
4097
+ * },
4098
+ * },
4099
+ * );
4100
+ * for await (const p of partialObjectStream) renderPreview(p);
4101
+ * console.log(await object);
4102
+ * ```
4103
+ */
4104
+ runObject(agentName, params) {
4105
+ const responseFormat = buildResponseFormat({
4106
+ schema: params.schema,
4107
+ ...params.schemaName !== void 0 ? { name: params.schemaName } : {},
4108
+ ...params.schemaDescription !== void 0 ? { description: params.schemaDescription } : {}
4109
+ });
4110
+ const sourceParts = this.runStreamParts(agentName, {
4111
+ messages: params.messages,
4112
+ ...params.signal !== void 0 ? { signal: params.signal } : {},
4113
+ responseFormat
4114
+ });
4115
+ const inner = createStreamResultFromParts(sourceParts);
4116
+ return wrapStreamTextAsObject(inner);
4117
+ }
4118
+ /** Non-streaming variant of {@link runObject}. */
4119
+ async generateObject(agentName, params) {
4120
+ const result = this.runObject(agentName, params);
4121
+ for await (const _ of result.partialObjectStream) void _;
4122
+ const [object, usage, finishReason, toolCalls] = await Promise.all([
4123
+ result.object,
4124
+ result.usage,
4125
+ result.finishReason,
4126
+ result.toolCalls
4127
+ ]);
4128
+ return { object, usage, finishReason, toolCalls };
4129
+ }
3694
4130
  async *runStreamParts(agentName, params) {
3695
4131
  const { messages } = params;
3696
4132
  if (!Array.isArray(messages) || messages.length === 0) {
@@ -3712,12 +4148,33 @@ var RagableBrowserAgentsClient = class {
3712
4148
  role: m.role,
3713
4149
  content: m.content
3714
4150
  }));
3715
- const events = this.chatStreamByName(agentName, {
4151
+ const headers = new Headers(this.options.headers);
4152
+ headers.set("Content-Type", "application/json");
4153
+ const body = {
3716
4154
  message: last.content,
3717
4155
  ...history.length > 0 ? { history } : {},
3718
- ...params.signal !== void 0 ? { signal: params.signal } : {}
3719
- });
3720
- for await (const event of events) {
4156
+ ...params.responseFormat ? { response_format: params.responseFormat } : {}
4157
+ };
4158
+ const response = await this.fetchImpl(
4159
+ this.toUrl(
4160
+ this.websiteAgentPath(
4161
+ `/agents/${encodeURIComponent(agentName)}/chat/stream`
4162
+ )
4163
+ ),
4164
+ {
4165
+ method: "POST",
4166
+ headers,
4167
+ body: JSON.stringify(body),
4168
+ ...params.signal !== void 0 ? { signal: params.signal } : {}
4169
+ }
4170
+ );
4171
+ if (!response.ok) {
4172
+ const payload = await parseMaybeJsonBody(response);
4173
+ const message = extractErrorMessage(payload, response.statusText);
4174
+ throw new RagableError(message, response.status, payload);
4175
+ }
4176
+ if (!response.body) return;
4177
+ for await (const event of readSseStream(response.body)) {
3721
4178
  const mapped = mapAgentEvent(event);
3722
4179
  if (mapped) yield mapped;
3723
4180
  }
@@ -3858,6 +4315,7 @@ var RagableBrowser = class {
3858
4315
  __publicField(this, "database");
3859
4316
  __publicField(this, "db");
3860
4317
  __publicField(this, "storage");
4318
+ __publicField(this, "mail");
3861
4319
  __publicField(this, "transport");
3862
4320
  __publicField(this, "_ragableAuth");
3863
4321
  /** Delegates to `database.from()`. Kept for back-compat — prefer `database.from()`. */
@@ -3903,6 +4361,7 @@ var RagableBrowser = class {
3903
4361
  this.database._setTransport(this.transport);
3904
4362
  this.db = this.database;
3905
4363
  this.storage = new RagableBrowserStorageClient(options, bindFetch(options.fetch));
4364
+ this.mail = new RagableBrowserMailClient(options, this._ragableAuth);
3906
4365
  }
3907
4366
  destroy() {
3908
4367
  this._ragableAuth?.destroy();
@@ -3944,6 +4403,7 @@ function createClient(options) {
3944
4403
  RagableBrowserAiClient,
3945
4404
  RagableBrowserAuthClient,
3946
4405
  RagableBrowserDatabaseClient,
4406
+ RagableBrowserMailClient,
3947
4407
  RagableBrowserStorageClient,
3948
4408
  RagableError,
3949
4409
  RagableNetworkError,
@@ -3955,6 +4415,7 @@ function createClient(options) {
3955
4415
  assertPostgrestSuccess,
3956
4416
  bindFetch,
3957
4417
  buildInferenceRequestBody,
4418
+ buildResponseFormat,
3958
4419
  collectAssistantTextFromUiSegments,
3959
4420
  collectionRecordToRowWithMeta,
3960
4421
  collectionRecordsToRowWithMeta,
@@ -3982,7 +4443,10 @@ function createClient(options) {
3982
4443
  runAgentChatStream,
3983
4444
  runAgentChatStreamForUi,
3984
4445
  runAgentChatStreamLenient,
4446
+ streamObjectFromContext,
3985
4447
  toRagableResult,
3986
- unwrapPostgrest
4448
+ tryParsePartialJson,
4449
+ unwrapPostgrest,
4450
+ wrapStreamTextAsObject
3987
4451
  });
3988
4452
  //# sourceMappingURL=index.js.map