@ragable/sdk 0.7.6 → 0.7.8

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.mjs CHANGED
@@ -131,201 +131,6 @@ function extractErrorMessage(payload, fallback) {
131
131
  }
132
132
  return fallback || "Request failed";
133
133
  }
134
- var RagableRequestClient = class {
135
- constructor(options) {
136
- __publicField(this, "apiKey");
137
- __publicField(this, "baseUrl");
138
- __publicField(this, "fetchImpl");
139
- __publicField(this, "defaultHeaders");
140
- this.apiKey = options.apiKey;
141
- this.baseUrl = DEFAULT_RAGABLE_API_BASE.replace(/\/+$/, "");
142
- this.fetchImpl = bindFetch(options.fetch);
143
- this.defaultHeaders = options.headers;
144
- }
145
- toUrl(path) {
146
- const normalizedBase = this.baseUrl.replace(/\/+$/, "");
147
- const normalizedPath = path.startsWith("/") ? path : `/${path}`;
148
- return `${normalizedBase}${normalizedPath}`;
149
- }
150
- async request(path, options = {}) {
151
- const response = await this.rawFetch(path, options);
152
- const payload = await this.parseResponseBody(response);
153
- if (!response.ok) {
154
- const message = extractErrorMessage(payload, response.statusText);
155
- throw new RagableError(message, response.status, payload);
156
- }
157
- return payload;
158
- }
159
- /**
160
- * Low-level fetch with API key and JSON body encoding. Caller handles status and body.
161
- */
162
- async rawFetch(path, options = {}) {
163
- const headers = new Headers(this.defaultHeaders);
164
- headers.set("Authorization", `Bearer ${this.apiKey}`);
165
- let body = options.body;
166
- if (body !== void 0 && !isBodyInit(body)) {
167
- headers.set("Content-Type", "application/json");
168
- body = JSON.stringify(body);
169
- }
170
- return this.fetchImpl(this.toUrl(path), {
171
- ...options,
172
- headers,
173
- body
174
- });
175
- }
176
- async parseResponseBody(response) {
177
- if (response.status === 204) {
178
- return null;
179
- }
180
- const contentType = response.headers.get("content-type") ?? "";
181
- if (contentType.includes("application/json")) {
182
- return response.json();
183
- }
184
- return response.text();
185
- }
186
- };
187
- function isBodyInit(value) {
188
- return typeof value === "string" || value instanceof Blob || value instanceof FormData || value instanceof URLSearchParams || value instanceof ArrayBuffer || ArrayBuffer.isView(value);
189
- }
190
-
191
- // src/shift.ts
192
- var ShiftClient = class {
193
- constructor(client) {
194
- this.client = client;
195
- __publicField(this, "indexes");
196
- __publicField(this, "documents");
197
- __publicField(this, "entries");
198
- this.indexes = {
199
- list: async () => {
200
- return this.client.request("/v1/shift/indexes");
201
- },
202
- create: async (params) => {
203
- return this.client.request("/v1/shift/indexes", {
204
- method: "POST",
205
- body: params
206
- });
207
- },
208
- get: async (indexId) => {
209
- return this.client.request(`/v1/shift/indexes/${indexId}`);
210
- },
211
- update: async (indexId, params) => {
212
- return this.client.request(`/v1/shift/indexes/${indexId}`, {
213
- method: "PUT",
214
- body: params
215
- });
216
- },
217
- delete: async (indexId) => {
218
- return this.client.request(
219
- `/v1/shift/indexes/${indexId}`,
220
- {
221
- method: "DELETE"
222
- }
223
- );
224
- }
225
- };
226
- this.documents = {
227
- create: async (indexId, params) => {
228
- return this.client.request(
229
- `/v1/shift/indexes/${indexId}/documents`,
230
- {
231
- method: "POST",
232
- body: params
233
- }
234
- );
235
- },
236
- upload: async (indexId, params) => {
237
- const formData = new FormData();
238
- const fileName = resolveUploadFileName(params);
239
- const contentType = resolveUploadContentType(params);
240
- const file = normalizeUploadFile(params.file, contentType);
241
- formData.set("file", file, fileName);
242
- if (params.metadata) {
243
- formData.set("metadata", JSON.stringify(params.metadata));
244
- }
245
- if (typeof params.chunkSize === "number") {
246
- formData.set("chunkSize", String(params.chunkSize));
247
- }
248
- if (typeof params.chunkOverlap === "number") {
249
- formData.set("chunkOverlap", String(params.chunkOverlap));
250
- }
251
- return this.client.request(
252
- `/v1/shift/indexes/${indexId}/files`,
253
- {
254
- method: "POST",
255
- body: formData
256
- }
257
- );
258
- }
259
- };
260
- this.entries = {
261
- list: async (indexId, params = {}) => {
262
- const search = new URLSearchParams();
263
- if (typeof params.take === "number") {
264
- search.set("take", String(params.take));
265
- }
266
- if (typeof params.skip === "number") {
267
- search.set("skip", String(params.skip));
268
- }
269
- const suffix = search.size > 0 ? `?${search.toString()}` : "";
270
- return this.client.request(
271
- `/v1/shift/indexes/${indexId}/entries${suffix}`
272
- );
273
- },
274
- delete: async (indexId, entryId) => {
275
- return this.client.request(
276
- `/v1/shift/indexes/${indexId}/entries/${entryId}`,
277
- {
278
- method: "DELETE"
279
- }
280
- );
281
- }
282
- };
283
- }
284
- async search(indexId, params) {
285
- return this.client.request(
286
- `/v1/shift/indexes/${indexId}/search`,
287
- {
288
- method: "POST",
289
- body: params
290
- }
291
- );
292
- }
293
- };
294
- function resolveUploadFileName(params) {
295
- if (params.fileName) {
296
- return params.fileName;
297
- }
298
- if (isNamedBlob(params.file)) {
299
- return params.file.name;
300
- }
301
- return "upload.bin";
302
- }
303
- function resolveUploadContentType(params) {
304
- if (params.contentType) {
305
- return params.contentType;
306
- }
307
- if (params.file instanceof Blob && params.file.type) {
308
- return params.file.type;
309
- }
310
- return "application/octet-stream";
311
- }
312
- function normalizeUploadFile(file, contentType) {
313
- if (file instanceof Blob) {
314
- return file;
315
- }
316
- if (file instanceof Uint8Array) {
317
- return new Blob([toArrayBuffer(file)], { type: contentType });
318
- }
319
- return new Blob([file], { type: contentType });
320
- }
321
- function isNamedBlob(value) {
322
- return value instanceof Blob && "name" in value && typeof value.name === "string";
323
- }
324
- function toArrayBuffer(value) {
325
- const copy = new Uint8Array(value.byteLength);
326
- copy.set(value);
327
- return copy.buffer;
328
- }
329
134
 
330
135
  // src/agent-stream.ts
331
136
  function assertAborted(signal) {
@@ -831,72 +636,6 @@ async function* readSseStream(body) {
831
636
  }
832
637
  }
833
638
 
834
- // src/agents.ts
835
- var AgentsClient = class {
836
- constructor(client) {
837
- this.client = client;
838
- }
839
- async list() {
840
- return this.client.request("/v1/agents");
841
- }
842
- async get(agentId) {
843
- return this.client.request(`/v1/agents/${agentId}`);
844
- }
845
- async chat(agentId, params) {
846
- return this.client.request(`/v1/agents/${agentId}/chat`, {
847
- method: "POST",
848
- body: {
849
- message: params.message,
850
- ...params.history !== void 0 ? { history: params.history } : {}
851
- }
852
- });
853
- }
854
- /**
855
- * Stream agent execution as SSE (`data: {json}` lines). Yields parsed JSON objects.
856
- */
857
- async *chatStream(agentId, params) {
858
- const response = await this.client.rawFetch(
859
- `/v1/agents/${agentId}/chat/stream`,
860
- {
861
- method: "POST",
862
- body: {
863
- message: params.message,
864
- ...params.history !== void 0 ? { history: params.history } : {}
865
- },
866
- ...params.signal !== void 0 ? { signal: params.signal } : {}
867
- }
868
- );
869
- if (!response.ok) {
870
- const payload = await parseMaybeJsonBody(response);
871
- const message = extractErrorMessage(payload, response.statusText);
872
- throw new RagableError(message, response.status, payload);
873
- }
874
- const body = response.body;
875
- if (!body) {
876
- return;
877
- }
878
- yield* readSseStream(body);
879
- }
880
- /**
881
- * Stream an agent turn with callbacks; returns the final `done` payload plus streamed text.
882
- * Prefer this over manual iteration when building chat UIs against the server API key client.
883
- */
884
- async runChatStream(agentId, params, handlers = {}) {
885
- return runAgentChatStream(this.chatStream(agentId, params), handlers, {
886
- signal: params.signal
887
- });
888
- }
889
- /**
890
- * Stream with dashboard-style `AgentChat` ergonomics: {@link AgentChatStreamUiHandlers.onSegments}
891
- * / `onStreamingText` for live UI; returns a persisted-shaped assistant message on `done`.
892
- */
893
- async runChatUi(agentId, params, handlers = {}) {
894
- return runAgentChatStreamForUi(this.chatStream(agentId, params), handlers, {
895
- signal: params.signal
896
- });
897
- }
898
- };
899
-
900
639
  // src/transport.ts
901
640
  var DEFAULT_RETRY = {
902
641
  maxRetries: 3,
@@ -2125,8 +1864,8 @@ function parseExpiresInSeconds(raw) {
2125
1864
  const mult = u === "s" ? 1 : u === "m" ? 60 : u === "h" ? 3600 : u === "d" ? 86400 : 1;
2126
1865
  return n * mult;
2127
1866
  }
2128
- const asNum = Number(s);
2129
- return Number.isFinite(asNum) ? asNum : 0;
1867
+ const asNum2 = Number(s);
1868
+ return Number.isFinite(asNum2) ? asNum2 : 0;
2130
1869
  }
2131
1870
  async function parseJsonOrThrow(response) {
2132
1871
  const text = await response.text();
@@ -2530,6 +2269,740 @@ function decodeJwtExpiry(jwt) {
2530
2269
  }
2531
2270
  }
2532
2271
 
2272
+ // src/partial-json.ts
2273
+ function tryParsePartialJson(text) {
2274
+ const trimmed = text.trim();
2275
+ if (!trimmed) return void 0;
2276
+ try {
2277
+ return JSON.parse(trimmed);
2278
+ } catch {
2279
+ }
2280
+ const repaired = repairOpenStructures(trimmed);
2281
+ if (!repaired) return void 0;
2282
+ try {
2283
+ return JSON.parse(repaired);
2284
+ } catch {
2285
+ const noTrailingComma = stripTrailingCommas(trimmed);
2286
+ const repaired2 = repairOpenStructures(noTrailingComma);
2287
+ if (!repaired2) return void 0;
2288
+ try {
2289
+ return JSON.parse(repaired2);
2290
+ } catch {
2291
+ return void 0;
2292
+ }
2293
+ }
2294
+ }
2295
+ function repairOpenStructures(text) {
2296
+ const first = text[0];
2297
+ if (first !== "{" && first !== "[") {
2298
+ return text;
2299
+ }
2300
+ const stack = [];
2301
+ let inString = false;
2302
+ let escaped = false;
2303
+ for (let i = 0; i < text.length; i++) {
2304
+ const ch = text[i];
2305
+ if (escaped) {
2306
+ escaped = false;
2307
+ continue;
2308
+ }
2309
+ if (ch === "\\") {
2310
+ escaped = true;
2311
+ continue;
2312
+ }
2313
+ if (ch === '"') {
2314
+ inString = !inString;
2315
+ continue;
2316
+ }
2317
+ if (inString) continue;
2318
+ if (ch === "{") stack.push("}");
2319
+ else if (ch === "[") stack.push("]");
2320
+ else if (ch === "}" || ch === "]") {
2321
+ if (stack.length === 0) return null;
2322
+ stack.pop();
2323
+ }
2324
+ }
2325
+ let safe = text;
2326
+ if (inString) {
2327
+ safe += '"';
2328
+ }
2329
+ safe = safe.replace(/,\s*$/, "").replace(/:\s*$/, ": null");
2330
+ let suffix = "";
2331
+ for (let i = stack.length - 1; i >= 0; i--) suffix += stack[i];
2332
+ return safe + suffix;
2333
+ }
2334
+ function stripTrailingCommas(text) {
2335
+ return text.replace(/,(\s*[}\]])/g, "$1").replace(/,\s*$/, "");
2336
+ }
2337
+
2338
+ // src/stream-parts.ts
2339
+ function normalizeFinishReason(raw) {
2340
+ switch (raw) {
2341
+ case "stop":
2342
+ case "length":
2343
+ case "content-filter":
2344
+ case "error":
2345
+ return raw;
2346
+ case "tool_calls":
2347
+ return "tool-calls";
2348
+ case null:
2349
+ case void 0:
2350
+ case "":
2351
+ return "unknown";
2352
+ default:
2353
+ return "unknown";
2354
+ }
2355
+ }
2356
+ function chunkUsage(chunk) {
2357
+ const u = chunk.usage ?? {};
2358
+ const cached = u.prompt_tokens_details?.cached_tokens ?? u.cache_read_input_tokens;
2359
+ return {
2360
+ promptTokens: typeof u.prompt_tokens === "number" ? u.prompt_tokens : 0,
2361
+ completionTokens: typeof u.completion_tokens === "number" ? u.completion_tokens : 0,
2362
+ totalTokens: typeof u.total_tokens === "number" ? u.total_tokens : 0,
2363
+ ...typeof cached === "number" ? { cachedPromptTokens: cached } : {}
2364
+ };
2365
+ }
2366
+ function createToolCallAccumulator() {
2367
+ return { byIndex: /* @__PURE__ */ new Map() };
2368
+ }
2369
+ function parseJsonOrRaw(raw) {
2370
+ try {
2371
+ return JSON.parse(raw);
2372
+ } catch {
2373
+ return raw;
2374
+ }
2375
+ }
2376
+ function mapFireworksChunk(chunk, acc) {
2377
+ const out = [];
2378
+ if (chunk.error?.message) {
2379
+ out.push({ type: "error", error: chunk.error.message });
2380
+ return out;
2381
+ }
2382
+ const choice = chunk.choices?.[0];
2383
+ const delta = choice?.delta;
2384
+ if (delta?.content) {
2385
+ out.push({ type: "text-delta", textDelta: delta.content });
2386
+ }
2387
+ const reasoning = delta?.reasoning_content ?? delta?.reasoning;
2388
+ if (typeof reasoning === "string" && reasoning.length > 0) {
2389
+ out.push({ type: "reasoning", textDelta: reasoning });
2390
+ }
2391
+ if (Array.isArray(delta?.tool_calls)) {
2392
+ for (const tc of delta.tool_calls) {
2393
+ const idx = typeof tc.index === "number" ? tc.index : 0;
2394
+ let entry = acc.byIndex.get(idx);
2395
+ if (!entry) {
2396
+ entry = { id: "", name: "", argsBuffer: "", emitted: false };
2397
+ acc.byIndex.set(idx, entry);
2398
+ }
2399
+ if (tc.id) entry.id = tc.id;
2400
+ if (tc.function?.name) entry.name = tc.function.name;
2401
+ if (typeof tc.function?.arguments === "string") {
2402
+ entry.argsBuffer += tc.function.arguments;
2403
+ }
2404
+ }
2405
+ }
2406
+ if (choice?.finish_reason) {
2407
+ for (const entry of acc.byIndex.values()) {
2408
+ if (entry.emitted || !entry.name) continue;
2409
+ entry.emitted = true;
2410
+ out.push({
2411
+ type: "tool-call",
2412
+ toolCallId: entry.id || `call_${entry.name}_${Date.now()}`,
2413
+ toolName: entry.name,
2414
+ args: entry.argsBuffer ? parseJsonOrRaw(entry.argsBuffer) : {}
2415
+ });
2416
+ }
2417
+ out.push({
2418
+ type: "finish",
2419
+ finishReason: normalizeFinishReason(choice.finish_reason),
2420
+ usage: chunkUsage(chunk)
2421
+ });
2422
+ } else if (chunk.usage) {
2423
+ out.push({
2424
+ type: "finish",
2425
+ finishReason: "unknown",
2426
+ usage: chunkUsage(chunk)
2427
+ });
2428
+ }
2429
+ return out;
2430
+ }
2431
+ function asStr(v, fallback = "") {
2432
+ return typeof v === "string" ? v : fallback;
2433
+ }
2434
+ function asNum(v, fallback = 0) {
2435
+ return typeof v === "number" && Number.isFinite(v) ? v : fallback;
2436
+ }
2437
+ function mapAgentEvent(event) {
2438
+ switch (event.type) {
2439
+ case "token":
2440
+ return { type: "text-delta", textDelta: asStr(event.token) };
2441
+ case "reasoning_token":
2442
+ return { type: "reasoning", textDelta: asStr(event.token) };
2443
+ case "tool:call":
2444
+ return {
2445
+ type: "tool-call",
2446
+ toolCallId: asStr(event.nodeId),
2447
+ toolName: asStr(event.toolName),
2448
+ args: event.args
2449
+ };
2450
+ case "tool:result":
2451
+ return {
2452
+ type: "tool-result",
2453
+ toolCallId: asStr(event.nodeId),
2454
+ toolName: asStr(event.toolName),
2455
+ result: event.result,
2456
+ ...typeof event.durationMs === "number" ? { durationMs: event.durationMs } : {}
2457
+ };
2458
+ case "done": {
2459
+ const usage = {
2460
+ promptTokens: asNum(event.inputTokens),
2461
+ completionTokens: asNum(event.outputTokens),
2462
+ totalTokens: asNum(event.inputTokens) + asNum(event.outputTokens),
2463
+ ...typeof event.cachedPromptTokens === "number" ? { cachedPromptTokens: event.cachedPromptTokens } : {}
2464
+ };
2465
+ return {
2466
+ type: "finish",
2467
+ finishReason: normalizeFinishReason(
2468
+ asStr(event.finishReason) || asStr(event.stopReason) || null
2469
+ ),
2470
+ usage
2471
+ };
2472
+ }
2473
+ default:
2474
+ return null;
2475
+ }
2476
+ }
2477
+
2478
+ // src/ai.ts
2479
+ var PartBroadcast = class {
2480
+ constructor() {
2481
+ __publicField(this, "state", {
2482
+ parts: [],
2483
+ resolved: false,
2484
+ error: null,
2485
+ waiters: []
2486
+ });
2487
+ }
2488
+ push(part) {
2489
+ this.state.parts.push(part);
2490
+ this.notify();
2491
+ }
2492
+ end() {
2493
+ if (this.state.resolved) return;
2494
+ this.state.resolved = true;
2495
+ this.notify();
2496
+ }
2497
+ fail(error) {
2498
+ if (this.state.resolved) return;
2499
+ this.state.error = error;
2500
+ this.state.resolved = true;
2501
+ this.notify();
2502
+ }
2503
+ notify() {
2504
+ const waiters = this.state.waiters;
2505
+ this.state.waiters = [];
2506
+ for (const w of waiters) w();
2507
+ }
2508
+ consume() {
2509
+ const state = this.state;
2510
+ return {
2511
+ [Symbol.asyncIterator]: () => {
2512
+ let idx = 0;
2513
+ return {
2514
+ next: async () => {
2515
+ while (true) {
2516
+ if (idx < state.parts.length) {
2517
+ return { value: state.parts[idx++], done: false };
2518
+ }
2519
+ if (state.resolved) {
2520
+ if (state.error) throw state.error;
2521
+ return { value: void 0, done: true };
2522
+ }
2523
+ await new Promise((resolve) => {
2524
+ state.waiters.push(resolve);
2525
+ });
2526
+ }
2527
+ }
2528
+ };
2529
+ }
2530
+ };
2531
+ }
2532
+ };
2533
+ function defer() {
2534
+ let resolve;
2535
+ let reject;
2536
+ const promise = new Promise((res, rej) => {
2537
+ resolve = res;
2538
+ reject = rej;
2539
+ });
2540
+ return { promise, resolve, reject };
2541
+ }
2542
+ var ZERO_USAGE = {
2543
+ promptTokens: 0,
2544
+ completionTokens: 0,
2545
+ totalTokens: 0
2546
+ };
2547
+ function buildInferenceRequestBody(params, responseFormat) {
2548
+ const body = {
2549
+ model: params.model,
2550
+ messages: params.messages
2551
+ };
2552
+ if (params.system !== void 0) body.system = params.system;
2553
+ if (typeof params.temperature === "number")
2554
+ body.temperature = params.temperature;
2555
+ if (typeof params.maxTokens === "number") body.max_tokens = params.maxTokens;
2556
+ if (typeof params.topP === "number") body.top_p = params.topP;
2557
+ if (params.reasoningEffort) body.reasoning_effort = params.reasoningEffort;
2558
+ if (responseFormat) body.response_format = responseFormat;
2559
+ return body;
2560
+ }
2561
+ function buildResponseFormat(params) {
2562
+ const json_schema = {
2563
+ name: params.name ?? "Output",
2564
+ schema: params.schema,
2565
+ strict: params.strict ?? true
2566
+ };
2567
+ if (params.description) json_schema.description = params.description;
2568
+ return { type: "json_schema", json_schema };
2569
+ }
2570
+ async function consumeInferenceStream(body, broadcast, deferreds) {
2571
+ const reader = body.getReader();
2572
+ const decoder = new TextDecoder();
2573
+ const acc = createToolCallAccumulator();
2574
+ let textBuffer = "";
2575
+ let reasoningBuffer = "";
2576
+ let lastUsage = ZERO_USAGE;
2577
+ let lastFinish = "unknown";
2578
+ const toolCallsArr = [];
2579
+ let buffer = "";
2580
+ const dispatch = (rawLine) => {
2581
+ const parsed = parseSseDataLine(rawLine);
2582
+ if (!parsed) return;
2583
+ const chunk = parsed;
2584
+ const parts = mapFireworksChunk(chunk, acc);
2585
+ for (const part of parts) {
2586
+ if (part.type === "text-delta") textBuffer += part.textDelta;
2587
+ else if (part.type === "reasoning") reasoningBuffer += part.textDelta;
2588
+ else if (part.type === "tool-call") {
2589
+ toolCallsArr.push({
2590
+ toolCallId: part.toolCallId,
2591
+ toolName: part.toolName,
2592
+ args: part.args
2593
+ });
2594
+ } else if (part.type === "finish") {
2595
+ lastFinish = part.finishReason;
2596
+ lastUsage = part.usage;
2597
+ }
2598
+ broadcast.push(part);
2599
+ }
2600
+ };
2601
+ try {
2602
+ while (true) {
2603
+ const { done, value } = await reader.read();
2604
+ if (done) break;
2605
+ buffer += decoder.decode(value, { stream: true });
2606
+ let boundary = buffer.indexOf("\n\n");
2607
+ while (boundary !== -1) {
2608
+ const block = buffer.slice(0, boundary);
2609
+ buffer = buffer.slice(boundary + 2);
2610
+ for (const line of block.split("\n")) dispatch(line);
2611
+ boundary = buffer.indexOf("\n\n");
2612
+ }
2613
+ }
2614
+ if (buffer.trim().length > 0) {
2615
+ for (const line of buffer.split("\n")) dispatch(line);
2616
+ }
2617
+ broadcast.end();
2618
+ deferreds.text.resolve(textBuffer);
2619
+ deferreds.reasoning.resolve(reasoningBuffer);
2620
+ deferreds.usage.resolve(lastUsage);
2621
+ deferreds.finishReason.resolve(lastFinish);
2622
+ deferreds.toolCalls.resolve(toolCallsArr);
2623
+ } catch (error) {
2624
+ broadcast.fail(error);
2625
+ deferreds.text.reject(error);
2626
+ deferreds.reasoning.reject(error);
2627
+ deferreds.usage.reject(error);
2628
+ deferreds.finishReason.reject(error);
2629
+ deferreds.toolCalls.reject(error);
2630
+ } finally {
2631
+ try {
2632
+ reader.releaseLock();
2633
+ } catch {
2634
+ }
2635
+ }
2636
+ }
2637
+ function createStreamResultFromParts(source) {
2638
+ const broadcast = new PartBroadcast();
2639
+ const text = defer();
2640
+ const reasoning = defer();
2641
+ const usage = defer();
2642
+ const finishReason = defer();
2643
+ const toolCalls = defer();
2644
+ void (async () => {
2645
+ let textBuffer = "";
2646
+ let reasoningBuffer = "";
2647
+ let lastUsage = ZERO_USAGE;
2648
+ let lastFinish = "unknown";
2649
+ const toolCallsArr = [];
2650
+ try {
2651
+ for await (const part of source) {
2652
+ if (part.type === "text-delta") textBuffer += part.textDelta;
2653
+ else if (part.type === "reasoning")
2654
+ reasoningBuffer += part.textDelta;
2655
+ else if (part.type === "tool-call") {
2656
+ toolCallsArr.push({
2657
+ toolCallId: part.toolCallId,
2658
+ toolName: part.toolName,
2659
+ args: part.args
2660
+ });
2661
+ } else if (part.type === "finish") {
2662
+ lastFinish = part.finishReason;
2663
+ lastUsage = part.usage;
2664
+ }
2665
+ broadcast.push(part);
2666
+ }
2667
+ broadcast.end();
2668
+ text.resolve(textBuffer);
2669
+ reasoning.resolve(reasoningBuffer);
2670
+ usage.resolve(lastUsage);
2671
+ finishReason.resolve(lastFinish);
2672
+ toolCalls.resolve(toolCallsArr);
2673
+ } catch (error) {
2674
+ broadcast.fail(error);
2675
+ text.reject(error);
2676
+ reasoning.reject(error);
2677
+ usage.reject(error);
2678
+ finishReason.reject(error);
2679
+ toolCalls.reject(error);
2680
+ }
2681
+ })();
2682
+ return {
2683
+ fullStream: broadcast.consume(),
2684
+ textStream: {
2685
+ [Symbol.asyncIterator]: () => {
2686
+ const inner = broadcast.consume()[Symbol.asyncIterator]();
2687
+ return {
2688
+ next: async () => {
2689
+ while (true) {
2690
+ const r = await inner.next();
2691
+ if (r.done)
2692
+ return { value: void 0, done: true };
2693
+ if (r.value.type === "text-delta") {
2694
+ return { value: r.value.textDelta, done: false };
2695
+ }
2696
+ }
2697
+ }
2698
+ };
2699
+ }
2700
+ },
2701
+ text: text.promise,
2702
+ reasoning: reasoning.promise,
2703
+ usage: usage.promise,
2704
+ finishReason: finishReason.promise,
2705
+ toolCalls: toolCalls.promise
2706
+ };
2707
+ }
2708
+ function streamInferenceFromContext(ctx, params) {
2709
+ const broadcast = new PartBroadcast();
2710
+ const text = defer();
2711
+ const reasoning = defer();
2712
+ const usage = defer();
2713
+ const finishReason = defer();
2714
+ const toolCalls = defer();
2715
+ const start = async () => {
2716
+ const response = await ctx.fetch(ctx.url, {
2717
+ method: "POST",
2718
+ headers: ctx.headers,
2719
+ body: JSON.stringify(buildInferenceRequestBody(params)),
2720
+ ...params.signal !== void 0 ? { signal: params.signal } : {}
2721
+ });
2722
+ if (!response.ok) {
2723
+ const payload = await parseMaybeJsonBody(response);
2724
+ const message = extractErrorMessage(payload, response.statusText);
2725
+ throw new RagableError(message, response.status, payload);
2726
+ }
2727
+ if (!response.body) {
2728
+ throw new RagableError("Inference stream has no body", 502, {
2729
+ code: "SDK_INFERENCE_STREAM_NO_BODY"
2730
+ });
2731
+ }
2732
+ await consumeInferenceStream(response.body, broadcast, {
2733
+ text,
2734
+ reasoning,
2735
+ usage,
2736
+ finishReason,
2737
+ toolCalls
2738
+ });
2739
+ };
2740
+ start().catch((err) => {
2741
+ broadcast.fail(err);
2742
+ text.reject(err);
2743
+ reasoning.reject(err);
2744
+ usage.reject(err);
2745
+ finishReason.reject(err);
2746
+ toolCalls.reject(err);
2747
+ });
2748
+ return {
2749
+ fullStream: broadcast.consume(),
2750
+ textStream: {
2751
+ [Symbol.asyncIterator]: () => {
2752
+ const inner = broadcast.consume()[Symbol.asyncIterator]();
2753
+ return {
2754
+ next: async () => {
2755
+ while (true) {
2756
+ const r = await inner.next();
2757
+ if (r.done) return { value: void 0, done: true };
2758
+ if (r.value.type === "text-delta") {
2759
+ return { value: r.value.textDelta, done: false };
2760
+ }
2761
+ }
2762
+ }
2763
+ };
2764
+ }
2765
+ },
2766
+ text: text.promise,
2767
+ reasoning: reasoning.promise,
2768
+ usage: usage.promise,
2769
+ finishReason: finishReason.promise,
2770
+ toolCalls: toolCalls.promise
2771
+ };
2772
+ }
2773
+ var RagableBrowserAiClient = class {
2774
+ constructor(options) {
2775
+ this.options = options;
2776
+ __publicField(this, "fetchImpl");
2777
+ this.fetchImpl = bindFetch(options.fetch);
2778
+ }
2779
+ requireWebsiteId() {
2780
+ const id = this.options.websiteId?.trim();
2781
+ if (!id) {
2782
+ throw new RagableError(
2783
+ "client.ai.streamText requires websiteId on the client. Pass createBrowserClient({ websiteId, organizationId, ... }).",
2784
+ 400,
2785
+ { code: "SDK_MISSING_WEBSITE_ID" }
2786
+ );
2787
+ }
2788
+ return id;
2789
+ }
2790
+ buildContext() {
2791
+ const url = `${this.options.apiBase}/public/organizations/${encodeURIComponent(
2792
+ this.options.organizationId
2793
+ )}/websites/${encodeURIComponent(
2794
+ this.requireWebsiteId()
2795
+ )}/inference/stream`;
2796
+ const headers = new Headers(this.options.headers);
2797
+ headers.set("Content-Type", "application/json");
2798
+ headers.set("Accept", "text/event-stream");
2799
+ return { url, headers, fetch: this.fetchImpl };
2800
+ }
2801
+ streamText(params) {
2802
+ return streamInferenceFromContext(this.buildContext(), params);
2803
+ }
2804
+ async generateText(params) {
2805
+ const result = this.streamText(params);
2806
+ for await (const _ of result.fullStream) {
2807
+ void _;
2808
+ }
2809
+ const [text, reasoning, usage, finishReason, toolCalls] = await Promise.all(
2810
+ [
2811
+ result.text,
2812
+ result.reasoning,
2813
+ result.usage,
2814
+ result.finishReason,
2815
+ result.toolCalls
2816
+ ]
2817
+ );
2818
+ return { text, reasoning, usage, finishReason, toolCalls };
2819
+ }
2820
+ /**
2821
+ * Stream a JSON-Schema-constrained response. Matches Vercel AI SDK's
2822
+ * `streamObject` shape — returns a synchronous result with `partialObjectStream`
2823
+ * (best-effort incremental parses) and `object` (the final parsed JSON).
2824
+ *
2825
+ * ```ts
2826
+ * const { partialObjectStream, object } = client.ai.streamObject({
2827
+ * model: "accounts/fireworks/models/kimi-k2p5",
2828
+ * schema: {
2829
+ * type: "object",
2830
+ * properties: {
2831
+ * title: { type: "string" },
2832
+ * tags: { type: "array", items: { type: "string" } },
2833
+ * },
2834
+ * required: ["title", "tags"],
2835
+ * },
2836
+ * messages: [{ role: "user", content: "Give me a blog post idea about AI." }],
2837
+ * });
2838
+ * for await (const partial of partialObjectStream) renderPreview(partial);
2839
+ * const final = await object;
2840
+ * ```
2841
+ */
2842
+ streamObject(params) {
2843
+ return streamObjectFromContext(this.buildContext(), params);
2844
+ }
2845
+ /**
2846
+ * Non-streaming variant of {@link streamObject}. Resolves once the model
2847
+ * finishes; rejects if the final text isn't valid JSON for the schema.
2848
+ */
2849
+ async generateObject(params) {
2850
+ const result = this.streamObject(params);
2851
+ for await (const _ of result.partialObjectStream) {
2852
+ void _;
2853
+ }
2854
+ const [object, usage, finishReason, toolCalls] = await Promise.all([
2855
+ result.object,
2856
+ result.usage,
2857
+ result.finishReason,
2858
+ result.toolCalls
2859
+ ]);
2860
+ return { object, usage, finishReason, toolCalls };
2861
+ }
2862
+ };
2863
+ function streamObjectFromContext(ctx, params) {
2864
+ const textParams = {
2865
+ model: params.model,
2866
+ messages: params.messages,
2867
+ ...params.system !== void 0 ? { system: params.system } : {},
2868
+ ...typeof params.temperature === "number" ? { temperature: params.temperature } : {},
2869
+ ...typeof params.maxTokens === "number" ? { maxTokens: params.maxTokens } : {},
2870
+ ...typeof params.topP === "number" ? { topP: params.topP } : {},
2871
+ ...params.signal !== void 0 ? { signal: params.signal } : {}
2872
+ };
2873
+ const responseFormat = buildResponseFormat({
2874
+ schema: params.schema,
2875
+ ...params.schemaName !== void 0 ? { name: params.schemaName } : {},
2876
+ ...params.schemaDescription !== void 0 ? { description: params.schemaDescription } : {}
2877
+ });
2878
+ const overrideCtx = {
2879
+ ...ctx,
2880
+ // Wrap fetch to substitute the body. We can't change buildInferenceRequestBody
2881
+ // signature on the call site cleanly, so intercept here.
2882
+ fetch: ((input, init) => {
2883
+ if (init && typeof init.body === "string") {
2884
+ const parsed = JSON.parse(init.body);
2885
+ parsed.response_format = responseFormat;
2886
+ const newInit = { ...init, body: JSON.stringify(parsed) };
2887
+ return ctx.fetch(input, newInit);
2888
+ }
2889
+ return ctx.fetch(input, init);
2890
+ })
2891
+ };
2892
+ const inner = streamInferenceFromContext(overrideCtx, textParams);
2893
+ return wrapStreamTextAsObject(inner);
2894
+ }
2895
+ function wrapStreamTextAsObject(inner) {
2896
+ const partialBroadcast = new PartialObjectBroadcast();
2897
+ const objectDeferred = defer();
2898
+ void (async () => {
2899
+ let acc = "";
2900
+ let lastEmitted = /* @__PURE__ */ Symbol("none");
2901
+ try {
2902
+ for await (const delta of inner.textStream) {
2903
+ acc += delta;
2904
+ const candidate = tryParsePartialJson(acc);
2905
+ if (candidate !== void 0 && !sameSnapshot(candidate, lastEmitted)) {
2906
+ lastEmitted = candidate;
2907
+ partialBroadcast.push(candidate);
2908
+ }
2909
+ }
2910
+ const finalText = await inner.text;
2911
+ let finalObj;
2912
+ try {
2913
+ finalObj = JSON.parse(finalText);
2914
+ } catch (e) {
2915
+ const err = new RagableError(
2916
+ `Model output is not valid JSON: ${e.message}`,
2917
+ 502,
2918
+ {
2919
+ code: "SDK_OBJECT_PARSE_FAILED",
2920
+ raw: finalText.slice(0, 1e3)
2921
+ }
2922
+ );
2923
+ partialBroadcast.fail(err);
2924
+ objectDeferred.reject(err);
2925
+ return;
2926
+ }
2927
+ if (!sameSnapshot(finalObj, lastEmitted)) {
2928
+ partialBroadcast.push(finalObj);
2929
+ }
2930
+ partialBroadcast.end();
2931
+ objectDeferred.resolve(finalObj);
2932
+ } catch (err) {
2933
+ partialBroadcast.fail(err);
2934
+ objectDeferred.reject(err);
2935
+ }
2936
+ })();
2937
+ return {
2938
+ textStream: inner.textStream,
2939
+ partialObjectStream: partialBroadcast.consume(),
2940
+ object: objectDeferred.promise,
2941
+ text: inner.text,
2942
+ usage: inner.usage,
2943
+ finishReason: inner.finishReason,
2944
+ toolCalls: inner.toolCalls
2945
+ };
2946
+ }
2947
+ function sameSnapshot(a, b) {
2948
+ if (a === b) return true;
2949
+ try {
2950
+ return JSON.stringify(a) === JSON.stringify(b);
2951
+ } catch {
2952
+ return false;
2953
+ }
2954
+ }
2955
+ var PartialObjectBroadcast = class {
2956
+ constructor() {
2957
+ __publicField(this, "items", []);
2958
+ __publicField(this, "resolved", false);
2959
+ __publicField(this, "error", null);
2960
+ __publicField(this, "waiters", []);
2961
+ }
2962
+ push(item) {
2963
+ this.items.push(item);
2964
+ this.notify();
2965
+ }
2966
+ end() {
2967
+ if (this.resolved) return;
2968
+ this.resolved = true;
2969
+ this.notify();
2970
+ }
2971
+ fail(error) {
2972
+ if (this.resolved) return;
2973
+ this.error = error;
2974
+ this.resolved = true;
2975
+ this.notify();
2976
+ }
2977
+ notify() {
2978
+ const w = this.waiters;
2979
+ this.waiters = [];
2980
+ for (const fn of w) fn();
2981
+ }
2982
+ consume() {
2983
+ const self = this;
2984
+ return {
2985
+ [Symbol.asyncIterator]: () => {
2986
+ let idx = 0;
2987
+ return {
2988
+ next: async () => {
2989
+ while (true) {
2990
+ if (idx < self.items.length) {
2991
+ return { value: self.items[idx++], done: false };
2992
+ }
2993
+ if (self.resolved) {
2994
+ if (self.error) throw self.error;
2995
+ return { value: void 0, done: true };
2996
+ }
2997
+ await new Promise((res) => self.waiters.push(res));
2998
+ }
2999
+ }
3000
+ };
3001
+ }
3002
+ };
3003
+ }
3004
+ };
3005
+
2533
3006
  // src/browser.ts
2534
3007
  function normalizeBrowserApiBase() {
2535
3008
  return DEFAULT_RAGABLE_API_BASE.replace(/\/+$/, "");
@@ -3373,6 +3846,136 @@ var RagableBrowserAgentsClient = class {
3373
3846
  }
3374
3847
  yield* readSseStream(streamBody);
3375
3848
  }
3849
+ /**
3850
+ * Stream a project agent defined in `agents/*.json` using the same result
3851
+ * shape as `client.ai.streamText`. Preferred over {@link chatStreamByName}
3852
+ * and {@link runChatStreamByName} — those remain for back-compat only.
3853
+ *
3854
+ * ```ts
3855
+ * const { textStream, text } = client.agents.run("support", {
3856
+ * messages: [{ role: "user", content: "I can't log in" }],
3857
+ * });
3858
+ * for await (const delta of textStream) process.stdout.write(delta);
3859
+ * console.log(await text);
3860
+ * ```
3861
+ */
3862
+ run(agentName, params) {
3863
+ const source = this.runStreamParts(agentName, params);
3864
+ return createStreamResultFromParts(source);
3865
+ }
3866
+ /**
3867
+ * Same agent, same tools/instructions/RAG — but constrain the final output
3868
+ * to a JSON Schema. Matches `client.ai.streamObject` exactly so callers can
3869
+ * swap between raw inference and an agent without changing call shape.
3870
+ *
3871
+ * Tool calling and structured output are **compatible**: the model may call
3872
+ * the agent's tools as usual; the final assistant message is the schema-
3873
+ * conformant JSON. The agent's `agents/<name>.json` is unchanged — whether
3874
+ * the run is conversational or structured is decided by the call site.
3875
+ *
3876
+ * ```ts
3877
+ * const { partialObjectStream, object } = client.agents.runObject<Plan>(
3878
+ * "planner",
3879
+ * {
3880
+ * messages: [{ role: "user", content: "Plan a 3-day trip to Kyoto." }],
3881
+ * schema: {
3882
+ * type: "object",
3883
+ * properties: {
3884
+ * days: {
3885
+ * type: "array",
3886
+ * items: { type: "object", properties: { date: { type: "string" }, activities: { type: "array", items: { type: "string" } } } },
3887
+ * },
3888
+ * },
3889
+ * required: ["days"],
3890
+ * },
3891
+ * },
3892
+ * );
3893
+ * for await (const p of partialObjectStream) renderPreview(p);
3894
+ * console.log(await object);
3895
+ * ```
3896
+ */
3897
+ runObject(agentName, params) {
3898
+ const responseFormat = buildResponseFormat({
3899
+ schema: params.schema,
3900
+ ...params.schemaName !== void 0 ? { name: params.schemaName } : {},
3901
+ ...params.schemaDescription !== void 0 ? { description: params.schemaDescription } : {}
3902
+ });
3903
+ const sourceParts = this.runStreamParts(agentName, {
3904
+ messages: params.messages,
3905
+ ...params.signal !== void 0 ? { signal: params.signal } : {},
3906
+ responseFormat
3907
+ });
3908
+ const inner = createStreamResultFromParts(sourceParts);
3909
+ return wrapStreamTextAsObject(inner);
3910
+ }
3911
+ /** Non-streaming variant of {@link runObject}. */
3912
+ async generateObject(agentName, params) {
3913
+ const result = this.runObject(agentName, params);
3914
+ for await (const _ of result.partialObjectStream) void _;
3915
+ const [object, usage, finishReason, toolCalls] = await Promise.all([
3916
+ result.object,
3917
+ result.usage,
3918
+ result.finishReason,
3919
+ result.toolCalls
3920
+ ]);
3921
+ return { object, usage, finishReason, toolCalls };
3922
+ }
3923
+ async *runStreamParts(agentName, params) {
3924
+ const { messages } = params;
3925
+ if (!Array.isArray(messages) || messages.length === 0) {
3926
+ throw new RagableError(
3927
+ "agents.run requires at least one message",
3928
+ 400,
3929
+ { code: "SDK_AGENTS_RUN_EMPTY_MESSAGES" }
3930
+ );
3931
+ }
3932
+ const last = messages[messages.length - 1];
3933
+ if (!last || last.role !== "user") {
3934
+ throw new RagableError(
3935
+ 'agents.run: the final message must have role "user"',
3936
+ 400,
3937
+ { code: "SDK_AGENTS_RUN_INVALID_LAST_MESSAGE" }
3938
+ );
3939
+ }
3940
+ const history = messages.slice(0, -1).filter((m) => m.role === "user" || m.role === "assistant").map((m) => ({
3941
+ role: m.role,
3942
+ content: m.content
3943
+ }));
3944
+ const headers = new Headers(this.options.headers);
3945
+ headers.set("Content-Type", "application/json");
3946
+ const body = {
3947
+ message: last.content,
3948
+ ...history.length > 0 ? { history } : {},
3949
+ ...params.responseFormat ? { response_format: params.responseFormat } : {}
3950
+ };
3951
+ const response = await this.fetchImpl(
3952
+ this.toUrl(
3953
+ this.websiteAgentPath(
3954
+ `/agents/${encodeURIComponent(agentName)}/chat/stream`
3955
+ )
3956
+ ),
3957
+ {
3958
+ method: "POST",
3959
+ headers,
3960
+ body: JSON.stringify(body),
3961
+ ...params.signal !== void 0 ? { signal: params.signal } : {}
3962
+ }
3963
+ );
3964
+ if (!response.ok) {
3965
+ const payload = await parseMaybeJsonBody(response);
3966
+ const message = extractErrorMessage(payload, response.statusText);
3967
+ throw new RagableError(message, response.status, payload);
3968
+ }
3969
+ if (!response.body) return;
3970
+ for await (const event of readSseStream(response.body)) {
3971
+ const mapped = mapAgentEvent(event);
3972
+ if (mapped) yield mapped;
3973
+ }
3974
+ }
3975
+ /**
3976
+ * @deprecated Use {@link run} for new code. This method is kept for
3977
+ * back-compat with the original chat-stream DX.
3978
+ */
3376
3979
  async *chatStreamByName(agentName, params) {
3377
3980
  const headers = new Headers(this.options.headers);
3378
3981
  headers.set("Content-Type", "application/json");
@@ -3401,8 +4004,9 @@ var RagableBrowserAgentsClient = class {
3401
4004
  yield* readSseStream(response.body);
3402
4005
  }
3403
4006
  /**
3404
- * Stream a project agent (`/agents/*.json`) with callbacks; returns the final `done` payload
3405
- * plus streamed assistant text. Prefer this over manual `for await` when building chat UIs.
4007
+ * @deprecated Use {@link run} for new code. Returns the legacy callback-based
4008
+ * result type leaking server internals; the new Vercel-style API exposes
4009
+ * `textStream` / `fullStream` / promises for `text`, `usage`, `finishReason`.
3406
4010
  */
3407
4011
  async runChatStreamByName(agentName, params, handlers = {}) {
3408
4012
  return runAgentChatStream(this.chatStreamByName(agentName, params), handlers, {
@@ -3499,6 +4103,7 @@ var RagableBrowserAgentsClient = class {
3499
4103
  var RagableBrowser = class {
3500
4104
  constructor(options) {
3501
4105
  __publicField(this, "agents");
4106
+ __publicField(this, "ai");
3502
4107
  __publicField(this, "auth");
3503
4108
  __publicField(this, "database");
3504
4109
  __publicField(this, "db");
@@ -3533,6 +4138,13 @@ var RagableBrowser = class {
3533
4138
  this._ragableAuth = null;
3534
4139
  }
3535
4140
  this.agents = new RagableBrowserAgentsClient(options);
4141
+ this.ai = new RagableBrowserAiClient({
4142
+ organizationId: options.organizationId,
4143
+ ...options.websiteId !== void 0 ? { websiteId: options.websiteId } : {},
4144
+ ...options.fetch !== void 0 ? { fetch: options.fetch } : {},
4145
+ ...options.headers !== void 0 ? { headers: options.headers } : {},
4146
+ apiBase: normalizeBrowserApiBase()
4147
+ });
3536
4148
  this.auth = new RagableBrowserAuthClient(options, this._ragableAuth);
3537
4149
  this.database = new RagableBrowserDatabaseClient(
3538
4150
  options,
@@ -3551,245 +4163,13 @@ function createBrowserClient(options) {
3551
4163
  }
3552
4164
  var createRagableBrowserClient = createBrowserClient;
3553
4165
 
3554
- // src/rag.ts
3555
- function formatRetrievalContext(results, options = {}) {
3556
- const header = options.header ?? "Relevant passages:\n";
3557
- const separator = options.separator ?? "\n\n";
3558
- const minScore = options.minScore;
3559
- let filtered = results;
3560
- if (typeof minScore === "number") {
3561
- filtered = results.filter((r) => r.score >= minScore);
3562
- }
3563
- const blocks = filtered.map((r, i) => {
3564
- const scoreSuffix = options.includeScores === true ? ` (score: ${r.score.toFixed(4)})` : "";
3565
- return `[${i + 1}]${scoreSuffix}
3566
- ${r.content.trim()}`;
3567
- });
3568
- let text = (blocks.length > 0 ? header : "") + blocks.join(separator);
3569
- if (typeof options.maxChars === "number" && text.length > options.maxChars) {
3570
- text = text.slice(0, options.maxChars).trimEnd() + "\n\u2026";
3571
- }
3572
- return text;
3573
- }
3574
- function createRagPipeline(client, options) {
3575
- const { indexId } = options;
3576
- return {
3577
- indexId,
3578
- ingestText(params) {
3579
- return client.shift.documents.create(indexId, params);
3580
- },
3581
- ingestFile(params) {
3582
- return client.shift.documents.upload(indexId, params);
3583
- },
3584
- search(params) {
3585
- return client.shift.search(indexId, params);
3586
- },
3587
- async retrieve(params) {
3588
- const { format: formatOpts, ...searchParams } = params;
3589
- const { results } = await client.shift.search(indexId, searchParams);
3590
- const context = formatRetrievalContext(results, formatOpts ?? {});
3591
- return { results, context };
3592
- }
3593
- };
3594
- }
3595
-
3596
- // src/storage.ts
3597
- function normalizeUploadFile2(file, contentType) {
3598
- if (file instanceof Blob) return file;
3599
- const u8 = file instanceof ArrayBuffer ? new Uint8Array(file) : new Uint8Array(file);
3600
- return new Blob([u8.buffer], contentType ? { type: contentType } : {});
3601
- }
3602
- var StorageClient = class {
3603
- constructor(client) {
3604
- this.client = client;
3605
- /**
3606
- * Bucket-level CRUD — list, create and delete buckets for this organisation.
3607
- */
3608
- __publicField(this, "buckets");
3609
- this.buckets = {
3610
- list: async (params) => {
3611
- const qs = new URLSearchParams();
3612
- if (params?.q) qs.set("q", params.q);
3613
- if (params?.status) qs.set("status", params.status);
3614
- if (params?.sort) qs.set("sort", params.sort);
3615
- const query = qs.toString();
3616
- return this.client.request(
3617
- `/v1/storage/buckets${query ? `?${query}` : ""}`
3618
- );
3619
- },
3620
- create: async (name) => {
3621
- return this.client.request("/v1/storage/buckets", {
3622
- method: "POST",
3623
- body: { name }
3624
- });
3625
- },
3626
- delete: async (bucketId) => {
3627
- return this.client.request(
3628
- `/v1/storage/buckets/${encodeURIComponent(bucketId)}`,
3629
- { method: "DELETE" }
3630
- );
3631
- }
3632
- };
3633
- }
3634
- /**
3635
- * Returns a {@link StorageBucketClient} scoped to the given bucket ID.
3636
- *
3637
- * All object operations (upload, download, list, copy, move, signed URLs, …)
3638
- * are performed through the returned client.
3639
- *
3640
- * @param bucketId The Ragable bucket ID obtained from `buckets.list()` or `buckets.create()`.
3641
- */
3642
- from(bucketId) {
3643
- const { client } = this;
3644
- const base = `/v1/storage/buckets/${encodeURIComponent(bucketId)}`;
3645
- return {
3646
- list: async (params) => {
3647
- const qs = new URLSearchParams();
3648
- if (params?.prefix) qs.set("prefix", params.prefix);
3649
- if (params?.delimiter) qs.set("delimiter", params.delimiter);
3650
- if (params?.maxResults != null)
3651
- qs.set("maxResults", String(params.maxResults));
3652
- if (params?.pageToken) qs.set("pageToken", params.pageToken);
3653
- const query = qs.toString();
3654
- return client.request(
3655
- `${base}/contents${query ? `?${query}` : ""}`
3656
- );
3657
- },
3658
- createFolder: async (folderPath) => {
3659
- return client.request(
3660
- `${base}/folders`,
3661
- { method: "POST", body: { folderPath } }
3662
- );
3663
- },
3664
- deleteFolder: async (folderPath) => {
3665
- return client.request(
3666
- `${base}/folders`,
3667
- { method: "DELETE", body: { folderPath } }
3668
- );
3669
- },
3670
- upload: async (params) => {
3671
- const formData = new FormData();
3672
- const blob = normalizeUploadFile2(params.file, params.contentType);
3673
- const fileName = params.fileName ?? "upload";
3674
- formData.set("file", blob, fileName);
3675
- formData.set("objectPath", params.objectPath);
3676
- if (params.cacheControl) {
3677
- formData.set("cacheControl", params.cacheControl);
3678
- }
3679
- return client.request(`${base}/upload`, {
3680
- method: "POST",
3681
- body: formData
3682
- });
3683
- },
3684
- delete: async (objectPath) => {
3685
- return client.request(
3686
- `${base}/objects`,
3687
- { method: "DELETE", body: { objectPath } }
3688
- );
3689
- },
3690
- bulkDelete: async (objectPaths) => {
3691
- return client.request(
3692
- `${base}/objects/delete-bulk`,
3693
- { method: "POST", body: { objectPaths } }
3694
- );
3695
- },
3696
- getMetadata: async (objectPath) => {
3697
- const qs = new URLSearchParams({ objectPath });
3698
- return client.request(
3699
- `${base}/objects/metadata?${qs}`
3700
- );
3701
- },
3702
- updateMetadata: async (params) => {
3703
- return client.request(
3704
- `${base}/objects/metadata`,
3705
- { method: "PATCH", body: params }
3706
- );
3707
- },
3708
- download: async (params) => {
3709
- const qs = new URLSearchParams({ objectPath: params.objectPath });
3710
- if (params.asText != null) qs.set("asText", String(params.asText));
3711
- if (params.maxTextBytes != null)
3712
- qs.set("maxTextBytes", String(params.maxTextBytes));
3713
- return client.request(
3714
- `${base}/objects/download?${qs}`
3715
- );
3716
- },
3717
- copy: async (params) => {
3718
- return client.request(`${base}/objects/copy`, { method: "POST", body: params });
3719
- },
3720
- move: async (params) => {
3721
- return client.request(`${base}/objects/move`, { method: "POST", body: params });
3722
- },
3723
- getSignedUploadUrl: async (params) => {
3724
- return client.request(
3725
- `${base}/signed-upload-url`,
3726
- { method: "POST", body: params }
3727
- );
3728
- },
3729
- getSignedDownloadUrl: async (params) => {
3730
- const qs = new URLSearchParams({ objectPath: params.objectPath });
3731
- if (params.expiresInSeconds != null)
3732
- qs.set("expiresInSeconds", String(params.expiresInSeconds));
3733
- return client.request(
3734
- `${base}/signed-download-url?${qs}`
3735
- );
3736
- },
3737
- getSettings: async () => {
3738
- return client.request(`${base}/settings`);
3739
- },
3740
- updateSettings: async (params) => {
3741
- return client.request(`${base}/settings`, {
3742
- method: "PATCH",
3743
- body: params
3744
- });
3745
- }
3746
- };
3747
- }
3748
- };
3749
-
3750
4166
  // src/index.ts
3751
- var Ragable = class {
3752
- constructor(options) {
3753
- __publicField(this, "shift");
3754
- __publicField(this, "agents");
3755
- __publicField(this, "storage");
3756
- __publicField(this, "infrastructure");
3757
- const client = new RagableRequestClient(options);
3758
- this.shift = new ShiftClient(client);
3759
- this.agents = new AgentsClient(client);
3760
- this.storage = new StorageClient(client);
3761
- this.infrastructure = {
3762
- shift: this.shift
3763
- };
3764
- }
3765
- };
3766
- function isServerClientOptions(o) {
3767
- return typeof o === "object" && o !== null && "apiKey" in o && typeof o.apiKey === "string" && o.apiKey.length > 0;
3768
- }
3769
4167
  function createClient(options) {
3770
- if (isServerClientOptions(options)) {
3771
- if (typeof options === "object" && options !== null && "organizationId" in options && typeof options.organizationId === "string") {
3772
- console.warn(
3773
- "[@ragable/sdk] createClient: `apiKey` is set, so the server client is returned. It has no `database` or `auth` \u2014 only `agents` and `shift`. For `db.collections.<name>` / `database.from()` / `auth.*`, use the browser client without `apiKey` (e.g. createClient({ organizationId, authGroupId, databaseInstanceId, ... }))."
3774
- );
3775
- }
3776
- return new Ragable(options);
3777
- }
3778
- if (typeof options === "object" && options !== null && "organizationId" in options && typeof options.organizationId === "string") {
3779
- return createBrowserClient(
3780
- options
3781
- );
3782
- }
3783
- throw new Error(
3784
- "createClient(options) requires apiKey (server) or organizationId (browser)"
3785
- );
3786
- }
3787
- function createRagableServerClient(options) {
3788
- return new Ragable(options);
4168
+ return createBrowserClient(options);
3789
4169
  }
3790
4170
  export {
3791
- AgentsClient,
3792
4171
  AuthBroadcastChannel,
4172
+ BrowserStorageBucketClient,
3793
4173
  CookieStorageAdapter,
3794
4174
  DEFAULT_RAGABLE_API_BASE,
3795
4175
  LocalStorageAdapter,
@@ -3806,43 +4186,43 @@ export {
3806
4186
  PostgrestUpdateRootBuilder,
3807
4187
  PostgrestUpsertReturningBuilder,
3808
4188
  PostgrestUpsertRootBuilder,
3809
- Ragable,
3810
4189
  RagableAbortError,
3811
4190
  RagableAuth,
3812
4191
  RagableBrowser,
3813
4192
  RagableBrowserAgentsClient,
4193
+ RagableBrowserAiClient,
3814
4194
  RagableBrowserAuthClient,
3815
4195
  RagableBrowserDatabaseClient,
4196
+ RagableBrowserStorageClient,
3816
4197
  RagableError,
3817
4198
  RagableNetworkError,
3818
- RagableRequestClient,
3819
4199
  RagableSdkError,
3820
4200
  RagableTimeoutError,
3821
4201
  SessionStorageAdapter,
3822
- ShiftClient,
3823
- StorageClient,
3824
4202
  Transport,
3825
4203
  asPostgrestResponse,
3826
4204
  assertPostgrestSuccess,
3827
4205
  bindFetch,
4206
+ buildInferenceRequestBody,
4207
+ buildResponseFormat,
3828
4208
  collectAssistantTextFromUiSegments,
3829
4209
  collectionRecordToRowWithMeta,
3830
4210
  collectionRecordsToRowWithMeta,
3831
4211
  createBrowserClient,
3832
4212
  createClient,
3833
- createRagPipeline,
3834
4213
  createRagableBrowserClient,
3835
- createRagableServerClient,
4214
+ createStreamResultFromParts,
3836
4215
  detectStorage,
3837
4216
  effectiveDataAuth,
3838
4217
  extractErrorMessage,
3839
4218
  finalizeAgentChatUiTurn,
3840
4219
  foldAgentStreamIntoUiSegments,
3841
4220
  formatPostgrestError,
3842
- formatRetrievalContext,
3843
4221
  formatSdkError,
3844
4222
  generateIdempotencyKey,
3845
4223
  isIncompleteAgentStreamError,
4224
+ mapAgentEvent,
4225
+ mapFireworksChunk,
3846
4226
  normalizeBrowserApiBase,
3847
4227
  parseAgentStreamAgentInfo,
3848
4228
  parseAgentStreamDone,
@@ -3852,7 +4232,10 @@ export {
3852
4232
  runAgentChatStream,
3853
4233
  runAgentChatStreamForUi,
3854
4234
  runAgentChatStreamLenient,
4235
+ streamObjectFromContext,
3855
4236
  toRagableResult,
3856
- unwrapPostgrest
4237
+ tryParsePartialJson,
4238
+ unwrapPostgrest,
4239
+ wrapStreamTextAsObject
3857
4240
  };
3858
4241
  //# sourceMappingURL=index.mjs.map