@ragable/sdk 0.7.6 → 0.7.7

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
@@ -22,8 +22,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
22
22
  // src/index.ts
23
23
  var index_exports = {};
24
24
  __export(index_exports, {
25
- AgentsClient: () => AgentsClient,
26
25
  AuthBroadcastChannel: () => AuthBroadcastChannel,
26
+ BrowserStorageBucketClient: () => BrowserStorageBucketClient,
27
27
  CookieStorageAdapter: () => CookieStorageAdapter,
28
28
  DEFAULT_RAGABLE_API_BASE: () => DEFAULT_RAGABLE_API_BASE,
29
29
  LocalStorageAdapter: () => LocalStorageAdapter,
@@ -40,43 +40,42 @@ __export(index_exports, {
40
40
  PostgrestUpdateRootBuilder: () => PostgrestUpdateRootBuilder,
41
41
  PostgrestUpsertReturningBuilder: () => PostgrestUpsertReturningBuilder,
42
42
  PostgrestUpsertRootBuilder: () => PostgrestUpsertRootBuilder,
43
- Ragable: () => Ragable,
44
43
  RagableAbortError: () => RagableAbortError,
45
44
  RagableAuth: () => RagableAuth,
46
45
  RagableBrowser: () => RagableBrowser,
47
46
  RagableBrowserAgentsClient: () => RagableBrowserAgentsClient,
47
+ RagableBrowserAiClient: () => RagableBrowserAiClient,
48
48
  RagableBrowserAuthClient: () => RagableBrowserAuthClient,
49
49
  RagableBrowserDatabaseClient: () => RagableBrowserDatabaseClient,
50
+ RagableBrowserStorageClient: () => RagableBrowserStorageClient,
50
51
  RagableError: () => RagableError,
51
52
  RagableNetworkError: () => RagableNetworkError,
52
- RagableRequestClient: () => RagableRequestClient,
53
53
  RagableSdkError: () => RagableSdkError,
54
54
  RagableTimeoutError: () => RagableTimeoutError,
55
55
  SessionStorageAdapter: () => SessionStorageAdapter,
56
- ShiftClient: () => ShiftClient,
57
- StorageClient: () => StorageClient,
58
56
  Transport: () => Transport,
59
57
  asPostgrestResponse: () => asPostgrestResponse,
60
58
  assertPostgrestSuccess: () => assertPostgrestSuccess,
61
59
  bindFetch: () => bindFetch,
60
+ buildInferenceRequestBody: () => buildInferenceRequestBody,
62
61
  collectAssistantTextFromUiSegments: () => collectAssistantTextFromUiSegments,
63
62
  collectionRecordToRowWithMeta: () => collectionRecordToRowWithMeta,
64
63
  collectionRecordsToRowWithMeta: () => collectionRecordsToRowWithMeta,
65
64
  createBrowserClient: () => createBrowserClient,
66
65
  createClient: () => createClient,
67
- createRagPipeline: () => createRagPipeline,
68
66
  createRagableBrowserClient: () => createRagableBrowserClient,
69
- createRagableServerClient: () => createRagableServerClient,
67
+ createStreamResultFromParts: () => createStreamResultFromParts,
70
68
  detectStorage: () => detectStorage,
71
69
  effectiveDataAuth: () => effectiveDataAuth,
72
70
  extractErrorMessage: () => extractErrorMessage,
73
71
  finalizeAgentChatUiTurn: () => finalizeAgentChatUiTurn,
74
72
  foldAgentStreamIntoUiSegments: () => foldAgentStreamIntoUiSegments,
75
73
  formatPostgrestError: () => formatPostgrestError,
76
- formatRetrievalContext: () => formatRetrievalContext,
77
74
  formatSdkError: () => formatSdkError,
78
75
  generateIdempotencyKey: () => generateIdempotencyKey,
79
76
  isIncompleteAgentStreamError: () => isIncompleteAgentStreamError,
77
+ mapAgentEvent: () => mapAgentEvent,
78
+ mapFireworksChunk: () => mapFireworksChunk,
80
79
  normalizeBrowserApiBase: () => normalizeBrowserApiBase,
81
80
  parseAgentStreamAgentInfo: () => parseAgentStreamAgentInfo,
82
81
  parseAgentStreamDone: () => parseAgentStreamDone,
@@ -220,201 +219,6 @@ function extractErrorMessage(payload, fallback) {
220
219
  }
221
220
  return fallback || "Request failed";
222
221
  }
223
- var RagableRequestClient = class {
224
- constructor(options) {
225
- __publicField(this, "apiKey");
226
- __publicField(this, "baseUrl");
227
- __publicField(this, "fetchImpl");
228
- __publicField(this, "defaultHeaders");
229
- this.apiKey = options.apiKey;
230
- this.baseUrl = DEFAULT_RAGABLE_API_BASE.replace(/\/+$/, "");
231
- this.fetchImpl = bindFetch(options.fetch);
232
- this.defaultHeaders = options.headers;
233
- }
234
- toUrl(path) {
235
- const normalizedBase = this.baseUrl.replace(/\/+$/, "");
236
- const normalizedPath = path.startsWith("/") ? path : `/${path}`;
237
- return `${normalizedBase}${normalizedPath}`;
238
- }
239
- async request(path, options = {}) {
240
- const response = await this.rawFetch(path, options);
241
- const payload = await this.parseResponseBody(response);
242
- if (!response.ok) {
243
- const message = extractErrorMessage(payload, response.statusText);
244
- throw new RagableError(message, response.status, payload);
245
- }
246
- return payload;
247
- }
248
- /**
249
- * Low-level fetch with API key and JSON body encoding. Caller handles status and body.
250
- */
251
- async rawFetch(path, options = {}) {
252
- const headers = new Headers(this.defaultHeaders);
253
- headers.set("Authorization", `Bearer ${this.apiKey}`);
254
- let body = options.body;
255
- if (body !== void 0 && !isBodyInit(body)) {
256
- headers.set("Content-Type", "application/json");
257
- body = JSON.stringify(body);
258
- }
259
- return this.fetchImpl(this.toUrl(path), {
260
- ...options,
261
- headers,
262
- body
263
- });
264
- }
265
- async parseResponseBody(response) {
266
- if (response.status === 204) {
267
- return null;
268
- }
269
- const contentType = response.headers.get("content-type") ?? "";
270
- if (contentType.includes("application/json")) {
271
- return response.json();
272
- }
273
- return response.text();
274
- }
275
- };
276
- function isBodyInit(value) {
277
- return typeof value === "string" || value instanceof Blob || value instanceof FormData || value instanceof URLSearchParams || value instanceof ArrayBuffer || ArrayBuffer.isView(value);
278
- }
279
-
280
- // src/shift.ts
281
- var ShiftClient = class {
282
- constructor(client) {
283
- this.client = client;
284
- __publicField(this, "indexes");
285
- __publicField(this, "documents");
286
- __publicField(this, "entries");
287
- this.indexes = {
288
- list: async () => {
289
- return this.client.request("/v1/shift/indexes");
290
- },
291
- create: async (params) => {
292
- return this.client.request("/v1/shift/indexes", {
293
- method: "POST",
294
- body: params
295
- });
296
- },
297
- get: async (indexId) => {
298
- return this.client.request(`/v1/shift/indexes/${indexId}`);
299
- },
300
- update: async (indexId, params) => {
301
- return this.client.request(`/v1/shift/indexes/${indexId}`, {
302
- method: "PUT",
303
- body: params
304
- });
305
- },
306
- delete: async (indexId) => {
307
- return this.client.request(
308
- `/v1/shift/indexes/${indexId}`,
309
- {
310
- method: "DELETE"
311
- }
312
- );
313
- }
314
- };
315
- this.documents = {
316
- create: async (indexId, params) => {
317
- return this.client.request(
318
- `/v1/shift/indexes/${indexId}/documents`,
319
- {
320
- method: "POST",
321
- body: params
322
- }
323
- );
324
- },
325
- upload: async (indexId, params) => {
326
- const formData = new FormData();
327
- const fileName = resolveUploadFileName(params);
328
- const contentType = resolveUploadContentType(params);
329
- const file = normalizeUploadFile(params.file, contentType);
330
- formData.set("file", file, fileName);
331
- if (params.metadata) {
332
- formData.set("metadata", JSON.stringify(params.metadata));
333
- }
334
- if (typeof params.chunkSize === "number") {
335
- formData.set("chunkSize", String(params.chunkSize));
336
- }
337
- if (typeof params.chunkOverlap === "number") {
338
- formData.set("chunkOverlap", String(params.chunkOverlap));
339
- }
340
- return this.client.request(
341
- `/v1/shift/indexes/${indexId}/files`,
342
- {
343
- method: "POST",
344
- body: formData
345
- }
346
- );
347
- }
348
- };
349
- this.entries = {
350
- list: async (indexId, params = {}) => {
351
- const search = new URLSearchParams();
352
- if (typeof params.take === "number") {
353
- search.set("take", String(params.take));
354
- }
355
- if (typeof params.skip === "number") {
356
- search.set("skip", String(params.skip));
357
- }
358
- const suffix = search.size > 0 ? `?${search.toString()}` : "";
359
- return this.client.request(
360
- `/v1/shift/indexes/${indexId}/entries${suffix}`
361
- );
362
- },
363
- delete: async (indexId, entryId) => {
364
- return this.client.request(
365
- `/v1/shift/indexes/${indexId}/entries/${entryId}`,
366
- {
367
- method: "DELETE"
368
- }
369
- );
370
- }
371
- };
372
- }
373
- async search(indexId, params) {
374
- return this.client.request(
375
- `/v1/shift/indexes/${indexId}/search`,
376
- {
377
- method: "POST",
378
- body: params
379
- }
380
- );
381
- }
382
- };
383
- function resolveUploadFileName(params) {
384
- if (params.fileName) {
385
- return params.fileName;
386
- }
387
- if (isNamedBlob(params.file)) {
388
- return params.file.name;
389
- }
390
- return "upload.bin";
391
- }
392
- function resolveUploadContentType(params) {
393
- if (params.contentType) {
394
- return params.contentType;
395
- }
396
- if (params.file instanceof Blob && params.file.type) {
397
- return params.file.type;
398
- }
399
- return "application/octet-stream";
400
- }
401
- function normalizeUploadFile(file, contentType) {
402
- if (file instanceof Blob) {
403
- return file;
404
- }
405
- if (file instanceof Uint8Array) {
406
- return new Blob([toArrayBuffer(file)], { type: contentType });
407
- }
408
- return new Blob([file], { type: contentType });
409
- }
410
- function isNamedBlob(value) {
411
- return value instanceof Blob && "name" in value && typeof value.name === "string";
412
- }
413
- function toArrayBuffer(value) {
414
- const copy = new Uint8Array(value.byteLength);
415
- copy.set(value);
416
- return copy.buffer;
417
- }
418
222
 
419
223
  // src/agent-stream.ts
420
224
  function assertAborted(signal) {
@@ -920,72 +724,6 @@ async function* readSseStream(body) {
920
724
  }
921
725
  }
922
726
 
923
- // src/agents.ts
924
- var AgentsClient = class {
925
- constructor(client) {
926
- this.client = client;
927
- }
928
- async list() {
929
- return this.client.request("/v1/agents");
930
- }
931
- async get(agentId) {
932
- return this.client.request(`/v1/agents/${agentId}`);
933
- }
934
- async chat(agentId, params) {
935
- return this.client.request(`/v1/agents/${agentId}/chat`, {
936
- method: "POST",
937
- body: {
938
- message: params.message,
939
- ...params.history !== void 0 ? { history: params.history } : {}
940
- }
941
- });
942
- }
943
- /**
944
- * Stream agent execution as SSE (`data: {json}` lines). Yields parsed JSON objects.
945
- */
946
- async *chatStream(agentId, params) {
947
- const response = await this.client.rawFetch(
948
- `/v1/agents/${agentId}/chat/stream`,
949
- {
950
- method: "POST",
951
- body: {
952
- message: params.message,
953
- ...params.history !== void 0 ? { history: params.history } : {}
954
- },
955
- ...params.signal !== void 0 ? { signal: params.signal } : {}
956
- }
957
- );
958
- if (!response.ok) {
959
- const payload = await parseMaybeJsonBody(response);
960
- const message = extractErrorMessage(payload, response.statusText);
961
- throw new RagableError(message, response.status, payload);
962
- }
963
- const body = response.body;
964
- if (!body) {
965
- return;
966
- }
967
- yield* readSseStream(body);
968
- }
969
- /**
970
- * Stream an agent turn with callbacks; returns the final `done` payload plus streamed text.
971
- * Prefer this over manual iteration when building chat UIs against the server API key client.
972
- */
973
- async runChatStream(agentId, params, handlers = {}) {
974
- return runAgentChatStream(this.chatStream(agentId, params), handlers, {
975
- signal: params.signal
976
- });
977
- }
978
- /**
979
- * Stream with dashboard-style `AgentChat` ergonomics: {@link AgentChatStreamUiHandlers.onSegments}
980
- * / `onStreamingText` for live UI; returns a persisted-shaped assistant message on `done`.
981
- */
982
- async runChatUi(agentId, params, handlers = {}) {
983
- return runAgentChatStreamForUi(this.chatStream(agentId, params), handlers, {
984
- signal: params.signal
985
- });
986
- }
987
- };
988
-
989
727
  // src/transport.ts
990
728
  var DEFAULT_RETRY = {
991
729
  maxRetries: 3,
@@ -2214,8 +1952,8 @@ function parseExpiresInSeconds(raw) {
2214
1952
  const mult = u === "s" ? 1 : u === "m" ? 60 : u === "h" ? 3600 : u === "d" ? 86400 : 1;
2215
1953
  return n * mult;
2216
1954
  }
2217
- const asNum = Number(s);
2218
- return Number.isFinite(asNum) ? asNum : 0;
1955
+ const asNum2 = Number(s);
1956
+ return Number.isFinite(asNum2) ? asNum2 : 0;
2219
1957
  }
2220
1958
  async function parseJsonOrThrow(response) {
2221
1959
  const text = await response.text();
@@ -2619,6 +2357,480 @@ function decodeJwtExpiry(jwt) {
2619
2357
  }
2620
2358
  }
2621
2359
 
2360
+ // src/stream-parts.ts
2361
+ function normalizeFinishReason(raw) {
2362
+ switch (raw) {
2363
+ case "stop":
2364
+ case "length":
2365
+ case "content-filter":
2366
+ case "error":
2367
+ return raw;
2368
+ case "tool_calls":
2369
+ return "tool-calls";
2370
+ case null:
2371
+ case void 0:
2372
+ case "":
2373
+ return "unknown";
2374
+ default:
2375
+ return "unknown";
2376
+ }
2377
+ }
2378
+ function chunkUsage(chunk) {
2379
+ const u = chunk.usage ?? {};
2380
+ const cached = u.prompt_tokens_details?.cached_tokens ?? u.cache_read_input_tokens;
2381
+ return {
2382
+ promptTokens: typeof u.prompt_tokens === "number" ? u.prompt_tokens : 0,
2383
+ completionTokens: typeof u.completion_tokens === "number" ? u.completion_tokens : 0,
2384
+ totalTokens: typeof u.total_tokens === "number" ? u.total_tokens : 0,
2385
+ ...typeof cached === "number" ? { cachedPromptTokens: cached } : {}
2386
+ };
2387
+ }
2388
+ function createToolCallAccumulator() {
2389
+ return { byIndex: /* @__PURE__ */ new Map() };
2390
+ }
2391
+ function parseJsonOrRaw(raw) {
2392
+ try {
2393
+ return JSON.parse(raw);
2394
+ } catch {
2395
+ return raw;
2396
+ }
2397
+ }
2398
+ function mapFireworksChunk(chunk, acc) {
2399
+ const out = [];
2400
+ if (chunk.error?.message) {
2401
+ out.push({ type: "error", error: chunk.error.message });
2402
+ return out;
2403
+ }
2404
+ const choice = chunk.choices?.[0];
2405
+ const delta = choice?.delta;
2406
+ if (delta?.content) {
2407
+ out.push({ type: "text-delta", textDelta: delta.content });
2408
+ }
2409
+ const reasoning = delta?.reasoning_content ?? delta?.reasoning;
2410
+ if (typeof reasoning === "string" && reasoning.length > 0) {
2411
+ out.push({ type: "reasoning", textDelta: reasoning });
2412
+ }
2413
+ if (Array.isArray(delta?.tool_calls)) {
2414
+ for (const tc of delta.tool_calls) {
2415
+ const idx = typeof tc.index === "number" ? tc.index : 0;
2416
+ let entry = acc.byIndex.get(idx);
2417
+ if (!entry) {
2418
+ entry = { id: "", name: "", argsBuffer: "", emitted: false };
2419
+ acc.byIndex.set(idx, entry);
2420
+ }
2421
+ if (tc.id) entry.id = tc.id;
2422
+ if (tc.function?.name) entry.name = tc.function.name;
2423
+ if (typeof tc.function?.arguments === "string") {
2424
+ entry.argsBuffer += tc.function.arguments;
2425
+ }
2426
+ }
2427
+ }
2428
+ if (choice?.finish_reason) {
2429
+ for (const entry of acc.byIndex.values()) {
2430
+ if (entry.emitted || !entry.name) continue;
2431
+ entry.emitted = true;
2432
+ out.push({
2433
+ type: "tool-call",
2434
+ toolCallId: entry.id || `call_${entry.name}_${Date.now()}`,
2435
+ toolName: entry.name,
2436
+ args: entry.argsBuffer ? parseJsonOrRaw(entry.argsBuffer) : {}
2437
+ });
2438
+ }
2439
+ out.push({
2440
+ type: "finish",
2441
+ finishReason: normalizeFinishReason(choice.finish_reason),
2442
+ usage: chunkUsage(chunk)
2443
+ });
2444
+ } else if (chunk.usage) {
2445
+ out.push({
2446
+ type: "finish",
2447
+ finishReason: "unknown",
2448
+ usage: chunkUsage(chunk)
2449
+ });
2450
+ }
2451
+ return out;
2452
+ }
2453
+ function asStr(v, fallback = "") {
2454
+ return typeof v === "string" ? v : fallback;
2455
+ }
2456
+ function asNum(v, fallback = 0) {
2457
+ return typeof v === "number" && Number.isFinite(v) ? v : fallback;
2458
+ }
2459
+ function mapAgentEvent(event) {
2460
+ switch (event.type) {
2461
+ case "token":
2462
+ return { type: "text-delta", textDelta: asStr(event.token) };
2463
+ case "reasoning_token":
2464
+ return { type: "reasoning", textDelta: asStr(event.token) };
2465
+ case "tool:call":
2466
+ return {
2467
+ type: "tool-call",
2468
+ toolCallId: asStr(event.nodeId),
2469
+ toolName: asStr(event.toolName),
2470
+ args: event.args
2471
+ };
2472
+ case "tool:result":
2473
+ return {
2474
+ type: "tool-result",
2475
+ toolCallId: asStr(event.nodeId),
2476
+ toolName: asStr(event.toolName),
2477
+ result: event.result,
2478
+ ...typeof event.durationMs === "number" ? { durationMs: event.durationMs } : {}
2479
+ };
2480
+ case "done": {
2481
+ const usage = {
2482
+ promptTokens: asNum(event.inputTokens),
2483
+ completionTokens: asNum(event.outputTokens),
2484
+ totalTokens: asNum(event.inputTokens) + asNum(event.outputTokens),
2485
+ ...typeof event.cachedPromptTokens === "number" ? { cachedPromptTokens: event.cachedPromptTokens } : {}
2486
+ };
2487
+ return {
2488
+ type: "finish",
2489
+ finishReason: normalizeFinishReason(
2490
+ asStr(event.finishReason) || asStr(event.stopReason) || null
2491
+ ),
2492
+ usage
2493
+ };
2494
+ }
2495
+ default:
2496
+ return null;
2497
+ }
2498
+ }
2499
+
2500
+ // src/ai.ts
2501
+ var PartBroadcast = class {
2502
+ constructor() {
2503
+ __publicField(this, "state", {
2504
+ parts: [],
2505
+ resolved: false,
2506
+ error: null,
2507
+ waiters: []
2508
+ });
2509
+ }
2510
+ push(part) {
2511
+ this.state.parts.push(part);
2512
+ this.notify();
2513
+ }
2514
+ end() {
2515
+ if (this.state.resolved) return;
2516
+ this.state.resolved = true;
2517
+ this.notify();
2518
+ }
2519
+ fail(error) {
2520
+ if (this.state.resolved) return;
2521
+ this.state.error = error;
2522
+ this.state.resolved = true;
2523
+ this.notify();
2524
+ }
2525
+ notify() {
2526
+ const waiters = this.state.waiters;
2527
+ this.state.waiters = [];
2528
+ for (const w of waiters) w();
2529
+ }
2530
+ consume() {
2531
+ const state = this.state;
2532
+ return {
2533
+ [Symbol.asyncIterator]: () => {
2534
+ let idx = 0;
2535
+ return {
2536
+ next: async () => {
2537
+ while (true) {
2538
+ if (idx < state.parts.length) {
2539
+ return { value: state.parts[idx++], done: false };
2540
+ }
2541
+ if (state.resolved) {
2542
+ if (state.error) throw state.error;
2543
+ return { value: void 0, done: true };
2544
+ }
2545
+ await new Promise((resolve) => {
2546
+ state.waiters.push(resolve);
2547
+ });
2548
+ }
2549
+ }
2550
+ };
2551
+ }
2552
+ };
2553
+ }
2554
+ };
2555
+ function defer() {
2556
+ let resolve;
2557
+ let reject;
2558
+ const promise = new Promise((res, rej) => {
2559
+ resolve = res;
2560
+ reject = rej;
2561
+ });
2562
+ return { promise, resolve, reject };
2563
+ }
2564
+ var ZERO_USAGE = {
2565
+ promptTokens: 0,
2566
+ completionTokens: 0,
2567
+ totalTokens: 0
2568
+ };
2569
+ function buildInferenceRequestBody(params) {
2570
+ const body = {
2571
+ model: params.model,
2572
+ messages: params.messages
2573
+ };
2574
+ if (params.system !== void 0) body.system = params.system;
2575
+ if (typeof params.temperature === "number")
2576
+ body.temperature = params.temperature;
2577
+ if (typeof params.maxTokens === "number") body.max_tokens = params.maxTokens;
2578
+ if (typeof params.topP === "number") body.top_p = params.topP;
2579
+ if (params.reasoningEffort) body.reasoning_effort = params.reasoningEffort;
2580
+ return body;
2581
+ }
2582
+ async function consumeInferenceStream(body, broadcast, deferreds) {
2583
+ const reader = body.getReader();
2584
+ const decoder = new TextDecoder();
2585
+ const acc = createToolCallAccumulator();
2586
+ let textBuffer = "";
2587
+ let reasoningBuffer = "";
2588
+ let lastUsage = ZERO_USAGE;
2589
+ let lastFinish = "unknown";
2590
+ const toolCallsArr = [];
2591
+ let buffer = "";
2592
+ const dispatch = (rawLine) => {
2593
+ const parsed = parseSseDataLine(rawLine);
2594
+ if (!parsed) return;
2595
+ const chunk = parsed;
2596
+ const parts = mapFireworksChunk(chunk, acc);
2597
+ for (const part of parts) {
2598
+ if (part.type === "text-delta") textBuffer += part.textDelta;
2599
+ else if (part.type === "reasoning") reasoningBuffer += part.textDelta;
2600
+ else if (part.type === "tool-call") {
2601
+ toolCallsArr.push({
2602
+ toolCallId: part.toolCallId,
2603
+ toolName: part.toolName,
2604
+ args: part.args
2605
+ });
2606
+ } else if (part.type === "finish") {
2607
+ lastFinish = part.finishReason;
2608
+ lastUsage = part.usage;
2609
+ }
2610
+ broadcast.push(part);
2611
+ }
2612
+ };
2613
+ try {
2614
+ while (true) {
2615
+ const { done, value } = await reader.read();
2616
+ if (done) break;
2617
+ buffer += decoder.decode(value, { stream: true });
2618
+ let boundary = buffer.indexOf("\n\n");
2619
+ while (boundary !== -1) {
2620
+ const block = buffer.slice(0, boundary);
2621
+ buffer = buffer.slice(boundary + 2);
2622
+ for (const line of block.split("\n")) dispatch(line);
2623
+ boundary = buffer.indexOf("\n\n");
2624
+ }
2625
+ }
2626
+ if (buffer.trim().length > 0) {
2627
+ for (const line of buffer.split("\n")) dispatch(line);
2628
+ }
2629
+ broadcast.end();
2630
+ deferreds.text.resolve(textBuffer);
2631
+ deferreds.reasoning.resolve(reasoningBuffer);
2632
+ deferreds.usage.resolve(lastUsage);
2633
+ deferreds.finishReason.resolve(lastFinish);
2634
+ deferreds.toolCalls.resolve(toolCallsArr);
2635
+ } catch (error) {
2636
+ broadcast.fail(error);
2637
+ deferreds.text.reject(error);
2638
+ deferreds.reasoning.reject(error);
2639
+ deferreds.usage.reject(error);
2640
+ deferreds.finishReason.reject(error);
2641
+ deferreds.toolCalls.reject(error);
2642
+ } finally {
2643
+ try {
2644
+ reader.releaseLock();
2645
+ } catch {
2646
+ }
2647
+ }
2648
+ }
2649
+ function createStreamResultFromParts(source) {
2650
+ const broadcast = new PartBroadcast();
2651
+ const text = defer();
2652
+ const reasoning = defer();
2653
+ const usage = defer();
2654
+ const finishReason = defer();
2655
+ const toolCalls = defer();
2656
+ void (async () => {
2657
+ let textBuffer = "";
2658
+ let reasoningBuffer = "";
2659
+ let lastUsage = ZERO_USAGE;
2660
+ let lastFinish = "unknown";
2661
+ const toolCallsArr = [];
2662
+ try {
2663
+ for await (const part of source) {
2664
+ if (part.type === "text-delta") textBuffer += part.textDelta;
2665
+ else if (part.type === "reasoning")
2666
+ reasoningBuffer += part.textDelta;
2667
+ else if (part.type === "tool-call") {
2668
+ toolCallsArr.push({
2669
+ toolCallId: part.toolCallId,
2670
+ toolName: part.toolName,
2671
+ args: part.args
2672
+ });
2673
+ } else if (part.type === "finish") {
2674
+ lastFinish = part.finishReason;
2675
+ lastUsage = part.usage;
2676
+ }
2677
+ broadcast.push(part);
2678
+ }
2679
+ broadcast.end();
2680
+ text.resolve(textBuffer);
2681
+ reasoning.resolve(reasoningBuffer);
2682
+ usage.resolve(lastUsage);
2683
+ finishReason.resolve(lastFinish);
2684
+ toolCalls.resolve(toolCallsArr);
2685
+ } catch (error) {
2686
+ broadcast.fail(error);
2687
+ text.reject(error);
2688
+ reasoning.reject(error);
2689
+ usage.reject(error);
2690
+ finishReason.reject(error);
2691
+ toolCalls.reject(error);
2692
+ }
2693
+ })();
2694
+ return {
2695
+ fullStream: broadcast.consume(),
2696
+ textStream: {
2697
+ [Symbol.asyncIterator]: () => {
2698
+ const inner = broadcast.consume()[Symbol.asyncIterator]();
2699
+ return {
2700
+ next: async () => {
2701
+ while (true) {
2702
+ const r = await inner.next();
2703
+ if (r.done)
2704
+ return { value: void 0, done: true };
2705
+ if (r.value.type === "text-delta") {
2706
+ return { value: r.value.textDelta, done: false };
2707
+ }
2708
+ }
2709
+ }
2710
+ };
2711
+ }
2712
+ },
2713
+ text: text.promise,
2714
+ reasoning: reasoning.promise,
2715
+ usage: usage.promise,
2716
+ finishReason: finishReason.promise,
2717
+ toolCalls: toolCalls.promise
2718
+ };
2719
+ }
2720
+ function streamInferenceFromContext(ctx, params) {
2721
+ const broadcast = new PartBroadcast();
2722
+ const text = defer();
2723
+ const reasoning = defer();
2724
+ const usage = defer();
2725
+ const finishReason = defer();
2726
+ const toolCalls = defer();
2727
+ const start = async () => {
2728
+ const response = await ctx.fetch(ctx.url, {
2729
+ method: "POST",
2730
+ headers: ctx.headers,
2731
+ body: JSON.stringify(buildInferenceRequestBody(params)),
2732
+ ...params.signal !== void 0 ? { signal: params.signal } : {}
2733
+ });
2734
+ if (!response.ok) {
2735
+ const payload = await parseMaybeJsonBody(response);
2736
+ const message = extractErrorMessage(payload, response.statusText);
2737
+ throw new RagableError(message, response.status, payload);
2738
+ }
2739
+ if (!response.body) {
2740
+ throw new RagableError("Inference stream has no body", 502, {
2741
+ code: "SDK_INFERENCE_STREAM_NO_BODY"
2742
+ });
2743
+ }
2744
+ await consumeInferenceStream(response.body, broadcast, {
2745
+ text,
2746
+ reasoning,
2747
+ usage,
2748
+ finishReason,
2749
+ toolCalls
2750
+ });
2751
+ };
2752
+ start().catch((err) => {
2753
+ broadcast.fail(err);
2754
+ text.reject(err);
2755
+ reasoning.reject(err);
2756
+ usage.reject(err);
2757
+ finishReason.reject(err);
2758
+ toolCalls.reject(err);
2759
+ });
2760
+ return {
2761
+ fullStream: broadcast.consume(),
2762
+ textStream: {
2763
+ [Symbol.asyncIterator]: () => {
2764
+ const inner = broadcast.consume()[Symbol.asyncIterator]();
2765
+ return {
2766
+ next: async () => {
2767
+ while (true) {
2768
+ const r = await inner.next();
2769
+ if (r.done) return { value: void 0, done: true };
2770
+ if (r.value.type === "text-delta") {
2771
+ return { value: r.value.textDelta, done: false };
2772
+ }
2773
+ }
2774
+ }
2775
+ };
2776
+ }
2777
+ },
2778
+ text: text.promise,
2779
+ reasoning: reasoning.promise,
2780
+ usage: usage.promise,
2781
+ finishReason: finishReason.promise,
2782
+ toolCalls: toolCalls.promise
2783
+ };
2784
+ }
2785
+ var RagableBrowserAiClient = class {
2786
+ constructor(options) {
2787
+ this.options = options;
2788
+ __publicField(this, "fetchImpl");
2789
+ this.fetchImpl = bindFetch(options.fetch);
2790
+ }
2791
+ requireWebsiteId() {
2792
+ const id = this.options.websiteId?.trim();
2793
+ if (!id) {
2794
+ throw new RagableError(
2795
+ "client.ai.streamText requires websiteId on the client. Pass createBrowserClient({ websiteId, organizationId, ... }).",
2796
+ 400,
2797
+ { code: "SDK_MISSING_WEBSITE_ID" }
2798
+ );
2799
+ }
2800
+ return id;
2801
+ }
2802
+ buildContext() {
2803
+ const url = `${this.options.apiBase}/public/organizations/${encodeURIComponent(
2804
+ this.options.organizationId
2805
+ )}/websites/${encodeURIComponent(
2806
+ this.requireWebsiteId()
2807
+ )}/inference/stream`;
2808
+ const headers = new Headers(this.options.headers);
2809
+ headers.set("Content-Type", "application/json");
2810
+ headers.set("Accept", "text/event-stream");
2811
+ return { url, headers, fetch: this.fetchImpl };
2812
+ }
2813
+ streamText(params) {
2814
+ return streamInferenceFromContext(this.buildContext(), params);
2815
+ }
2816
+ async generateText(params) {
2817
+ const result = this.streamText(params);
2818
+ for await (const _ of result.fullStream) {
2819
+ void _;
2820
+ }
2821
+ const [text, reasoning, usage, finishReason, toolCalls] = await Promise.all(
2822
+ [
2823
+ result.text,
2824
+ result.reasoning,
2825
+ result.usage,
2826
+ result.finishReason,
2827
+ result.toolCalls
2828
+ ]
2829
+ );
2830
+ return { text, reasoning, usage, finishReason, toolCalls };
2831
+ }
2832
+ };
2833
+
2622
2834
  // src/browser.ts
2623
2835
  function normalizeBrowserApiBase() {
2624
2836
  return DEFAULT_RAGABLE_API_BASE.replace(/\/+$/, "");
@@ -3462,6 +3674,58 @@ var RagableBrowserAgentsClient = class {
3462
3674
  }
3463
3675
  yield* readSseStream(streamBody);
3464
3676
  }
3677
+ /**
3678
+ * Stream a project agent defined in `agents/*.json` using the same result
3679
+ * shape as `client.ai.streamText`. Preferred over {@link chatStreamByName}
3680
+ * and {@link runChatStreamByName} — those remain for back-compat only.
3681
+ *
3682
+ * ```ts
3683
+ * const { textStream, text } = client.agents.run("support", {
3684
+ * messages: [{ role: "user", content: "I can't log in" }],
3685
+ * });
3686
+ * for await (const delta of textStream) process.stdout.write(delta);
3687
+ * console.log(await text);
3688
+ * ```
3689
+ */
3690
+ run(agentName, params) {
3691
+ const source = this.runStreamParts(agentName, params);
3692
+ return createStreamResultFromParts(source);
3693
+ }
3694
+ async *runStreamParts(agentName, params) {
3695
+ const { messages } = params;
3696
+ if (!Array.isArray(messages) || messages.length === 0) {
3697
+ throw new RagableError(
3698
+ "agents.run requires at least one message",
3699
+ 400,
3700
+ { code: "SDK_AGENTS_RUN_EMPTY_MESSAGES" }
3701
+ );
3702
+ }
3703
+ const last = messages[messages.length - 1];
3704
+ if (!last || last.role !== "user") {
3705
+ throw new RagableError(
3706
+ 'agents.run: the final message must have role "user"',
3707
+ 400,
3708
+ { code: "SDK_AGENTS_RUN_INVALID_LAST_MESSAGE" }
3709
+ );
3710
+ }
3711
+ const history = messages.slice(0, -1).filter((m) => m.role === "user" || m.role === "assistant").map((m) => ({
3712
+ role: m.role,
3713
+ content: m.content
3714
+ }));
3715
+ const events = this.chatStreamByName(agentName, {
3716
+ message: last.content,
3717
+ ...history.length > 0 ? { history } : {},
3718
+ ...params.signal !== void 0 ? { signal: params.signal } : {}
3719
+ });
3720
+ for await (const event of events) {
3721
+ const mapped = mapAgentEvent(event);
3722
+ if (mapped) yield mapped;
3723
+ }
3724
+ }
3725
+ /**
3726
+ * @deprecated Use {@link run} for new code. This method is kept for
3727
+ * back-compat with the original chat-stream DX.
3728
+ */
3465
3729
  async *chatStreamByName(agentName, params) {
3466
3730
  const headers = new Headers(this.options.headers);
3467
3731
  headers.set("Content-Type", "application/json");
@@ -3490,8 +3754,9 @@ var RagableBrowserAgentsClient = class {
3490
3754
  yield* readSseStream(response.body);
3491
3755
  }
3492
3756
  /**
3493
- * Stream a project agent (`/agents/*.json`) with callbacks; returns the final `done` payload
3494
- * plus streamed assistant text. Prefer this over manual `for await` when building chat UIs.
3757
+ * @deprecated Use {@link run} for new code. Returns the legacy callback-based
3758
+ * result type leaking server internals; the new Vercel-style API exposes
3759
+ * `textStream` / `fullStream` / promises for `text`, `usage`, `finishReason`.
3495
3760
  */
3496
3761
  async runChatStreamByName(agentName, params, handlers = {}) {
3497
3762
  return runAgentChatStream(this.chatStreamByName(agentName, params), handlers, {
@@ -3588,6 +3853,7 @@ var RagableBrowserAgentsClient = class {
3588
3853
  var RagableBrowser = class {
3589
3854
  constructor(options) {
3590
3855
  __publicField(this, "agents");
3856
+ __publicField(this, "ai");
3591
3857
  __publicField(this, "auth");
3592
3858
  __publicField(this, "database");
3593
3859
  __publicField(this, "db");
@@ -3622,6 +3888,13 @@ var RagableBrowser = class {
3622
3888
  this._ragableAuth = null;
3623
3889
  }
3624
3890
  this.agents = new RagableBrowserAgentsClient(options);
3891
+ this.ai = new RagableBrowserAiClient({
3892
+ organizationId: options.organizationId,
3893
+ ...options.websiteId !== void 0 ? { websiteId: options.websiteId } : {},
3894
+ ...options.fetch !== void 0 ? { fetch: options.fetch } : {},
3895
+ ...options.headers !== void 0 ? { headers: options.headers } : {},
3896
+ apiBase: normalizeBrowserApiBase()
3897
+ });
3625
3898
  this.auth = new RagableBrowserAuthClient(options, this._ragableAuth);
3626
3899
  this.database = new RagableBrowserDatabaseClient(
3627
3900
  options,
@@ -3640,246 +3913,14 @@ function createBrowserClient(options) {
3640
3913
  }
3641
3914
  var createRagableBrowserClient = createBrowserClient;
3642
3915
 
3643
- // src/rag.ts
3644
- function formatRetrievalContext(results, options = {}) {
3645
- const header = options.header ?? "Relevant passages:\n";
3646
- const separator = options.separator ?? "\n\n";
3647
- const minScore = options.minScore;
3648
- let filtered = results;
3649
- if (typeof minScore === "number") {
3650
- filtered = results.filter((r) => r.score >= minScore);
3651
- }
3652
- const blocks = filtered.map((r, i) => {
3653
- const scoreSuffix = options.includeScores === true ? ` (score: ${r.score.toFixed(4)})` : "";
3654
- return `[${i + 1}]${scoreSuffix}
3655
- ${r.content.trim()}`;
3656
- });
3657
- let text = (blocks.length > 0 ? header : "") + blocks.join(separator);
3658
- if (typeof options.maxChars === "number" && text.length > options.maxChars) {
3659
- text = text.slice(0, options.maxChars).trimEnd() + "\n\u2026";
3660
- }
3661
- return text;
3662
- }
3663
- function createRagPipeline(client, options) {
3664
- const { indexId } = options;
3665
- return {
3666
- indexId,
3667
- ingestText(params) {
3668
- return client.shift.documents.create(indexId, params);
3669
- },
3670
- ingestFile(params) {
3671
- return client.shift.documents.upload(indexId, params);
3672
- },
3673
- search(params) {
3674
- return client.shift.search(indexId, params);
3675
- },
3676
- async retrieve(params) {
3677
- const { format: formatOpts, ...searchParams } = params;
3678
- const { results } = await client.shift.search(indexId, searchParams);
3679
- const context = formatRetrievalContext(results, formatOpts ?? {});
3680
- return { results, context };
3681
- }
3682
- };
3683
- }
3684
-
3685
- // src/storage.ts
3686
- function normalizeUploadFile2(file, contentType) {
3687
- if (file instanceof Blob) return file;
3688
- const u8 = file instanceof ArrayBuffer ? new Uint8Array(file) : new Uint8Array(file);
3689
- return new Blob([u8.buffer], contentType ? { type: contentType } : {});
3690
- }
3691
- var StorageClient = class {
3692
- constructor(client) {
3693
- this.client = client;
3694
- /**
3695
- * Bucket-level CRUD — list, create and delete buckets for this organisation.
3696
- */
3697
- __publicField(this, "buckets");
3698
- this.buckets = {
3699
- list: async (params) => {
3700
- const qs = new URLSearchParams();
3701
- if (params?.q) qs.set("q", params.q);
3702
- if (params?.status) qs.set("status", params.status);
3703
- if (params?.sort) qs.set("sort", params.sort);
3704
- const query = qs.toString();
3705
- return this.client.request(
3706
- `/v1/storage/buckets${query ? `?${query}` : ""}`
3707
- );
3708
- },
3709
- create: async (name) => {
3710
- return this.client.request("/v1/storage/buckets", {
3711
- method: "POST",
3712
- body: { name }
3713
- });
3714
- },
3715
- delete: async (bucketId) => {
3716
- return this.client.request(
3717
- `/v1/storage/buckets/${encodeURIComponent(bucketId)}`,
3718
- { method: "DELETE" }
3719
- );
3720
- }
3721
- };
3722
- }
3723
- /**
3724
- * Returns a {@link StorageBucketClient} scoped to the given bucket ID.
3725
- *
3726
- * All object operations (upload, download, list, copy, move, signed URLs, …)
3727
- * are performed through the returned client.
3728
- *
3729
- * @param bucketId The Ragable bucket ID obtained from `buckets.list()` or `buckets.create()`.
3730
- */
3731
- from(bucketId) {
3732
- const { client } = this;
3733
- const base = `/v1/storage/buckets/${encodeURIComponent(bucketId)}`;
3734
- return {
3735
- list: async (params) => {
3736
- const qs = new URLSearchParams();
3737
- if (params?.prefix) qs.set("prefix", params.prefix);
3738
- if (params?.delimiter) qs.set("delimiter", params.delimiter);
3739
- if (params?.maxResults != null)
3740
- qs.set("maxResults", String(params.maxResults));
3741
- if (params?.pageToken) qs.set("pageToken", params.pageToken);
3742
- const query = qs.toString();
3743
- return client.request(
3744
- `${base}/contents${query ? `?${query}` : ""}`
3745
- );
3746
- },
3747
- createFolder: async (folderPath) => {
3748
- return client.request(
3749
- `${base}/folders`,
3750
- { method: "POST", body: { folderPath } }
3751
- );
3752
- },
3753
- deleteFolder: async (folderPath) => {
3754
- return client.request(
3755
- `${base}/folders`,
3756
- { method: "DELETE", body: { folderPath } }
3757
- );
3758
- },
3759
- upload: async (params) => {
3760
- const formData = new FormData();
3761
- const blob = normalizeUploadFile2(params.file, params.contentType);
3762
- const fileName = params.fileName ?? "upload";
3763
- formData.set("file", blob, fileName);
3764
- formData.set("objectPath", params.objectPath);
3765
- if (params.cacheControl) {
3766
- formData.set("cacheControl", params.cacheControl);
3767
- }
3768
- return client.request(`${base}/upload`, {
3769
- method: "POST",
3770
- body: formData
3771
- });
3772
- },
3773
- delete: async (objectPath) => {
3774
- return client.request(
3775
- `${base}/objects`,
3776
- { method: "DELETE", body: { objectPath } }
3777
- );
3778
- },
3779
- bulkDelete: async (objectPaths) => {
3780
- return client.request(
3781
- `${base}/objects/delete-bulk`,
3782
- { method: "POST", body: { objectPaths } }
3783
- );
3784
- },
3785
- getMetadata: async (objectPath) => {
3786
- const qs = new URLSearchParams({ objectPath });
3787
- return client.request(
3788
- `${base}/objects/metadata?${qs}`
3789
- );
3790
- },
3791
- updateMetadata: async (params) => {
3792
- return client.request(
3793
- `${base}/objects/metadata`,
3794
- { method: "PATCH", body: params }
3795
- );
3796
- },
3797
- download: async (params) => {
3798
- const qs = new URLSearchParams({ objectPath: params.objectPath });
3799
- if (params.asText != null) qs.set("asText", String(params.asText));
3800
- if (params.maxTextBytes != null)
3801
- qs.set("maxTextBytes", String(params.maxTextBytes));
3802
- return client.request(
3803
- `${base}/objects/download?${qs}`
3804
- );
3805
- },
3806
- copy: async (params) => {
3807
- return client.request(`${base}/objects/copy`, { method: "POST", body: params });
3808
- },
3809
- move: async (params) => {
3810
- return client.request(`${base}/objects/move`, { method: "POST", body: params });
3811
- },
3812
- getSignedUploadUrl: async (params) => {
3813
- return client.request(
3814
- `${base}/signed-upload-url`,
3815
- { method: "POST", body: params }
3816
- );
3817
- },
3818
- getSignedDownloadUrl: async (params) => {
3819
- const qs = new URLSearchParams({ objectPath: params.objectPath });
3820
- if (params.expiresInSeconds != null)
3821
- qs.set("expiresInSeconds", String(params.expiresInSeconds));
3822
- return client.request(
3823
- `${base}/signed-download-url?${qs}`
3824
- );
3825
- },
3826
- getSettings: async () => {
3827
- return client.request(`${base}/settings`);
3828
- },
3829
- updateSettings: async (params) => {
3830
- return client.request(`${base}/settings`, {
3831
- method: "PATCH",
3832
- body: params
3833
- });
3834
- }
3835
- };
3836
- }
3837
- };
3838
-
3839
3916
  // src/index.ts
3840
- var Ragable = class {
3841
- constructor(options) {
3842
- __publicField(this, "shift");
3843
- __publicField(this, "agents");
3844
- __publicField(this, "storage");
3845
- __publicField(this, "infrastructure");
3846
- const client = new RagableRequestClient(options);
3847
- this.shift = new ShiftClient(client);
3848
- this.agents = new AgentsClient(client);
3849
- this.storage = new StorageClient(client);
3850
- this.infrastructure = {
3851
- shift: this.shift
3852
- };
3853
- }
3854
- };
3855
- function isServerClientOptions(o) {
3856
- return typeof o === "object" && o !== null && "apiKey" in o && typeof o.apiKey === "string" && o.apiKey.length > 0;
3857
- }
3858
3917
  function createClient(options) {
3859
- if (isServerClientOptions(options)) {
3860
- if (typeof options === "object" && options !== null && "organizationId" in options && typeof options.organizationId === "string") {
3861
- console.warn(
3862
- "[@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, ... }))."
3863
- );
3864
- }
3865
- return new Ragable(options);
3866
- }
3867
- if (typeof options === "object" && options !== null && "organizationId" in options && typeof options.organizationId === "string") {
3868
- return createBrowserClient(
3869
- options
3870
- );
3871
- }
3872
- throw new Error(
3873
- "createClient(options) requires apiKey (server) or organizationId (browser)"
3874
- );
3875
- }
3876
- function createRagableServerClient(options) {
3877
- return new Ragable(options);
3918
+ return createBrowserClient(options);
3878
3919
  }
3879
3920
  // Annotate the CommonJS export names for ESM import in node:
3880
3921
  0 && (module.exports = {
3881
- AgentsClient,
3882
3922
  AuthBroadcastChannel,
3923
+ BrowserStorageBucketClient,
3883
3924
  CookieStorageAdapter,
3884
3925
  DEFAULT_RAGABLE_API_BASE,
3885
3926
  LocalStorageAdapter,
@@ -3896,43 +3937,42 @@ function createRagableServerClient(options) {
3896
3937
  PostgrestUpdateRootBuilder,
3897
3938
  PostgrestUpsertReturningBuilder,
3898
3939
  PostgrestUpsertRootBuilder,
3899
- Ragable,
3900
3940
  RagableAbortError,
3901
3941
  RagableAuth,
3902
3942
  RagableBrowser,
3903
3943
  RagableBrowserAgentsClient,
3944
+ RagableBrowserAiClient,
3904
3945
  RagableBrowserAuthClient,
3905
3946
  RagableBrowserDatabaseClient,
3947
+ RagableBrowserStorageClient,
3906
3948
  RagableError,
3907
3949
  RagableNetworkError,
3908
- RagableRequestClient,
3909
3950
  RagableSdkError,
3910
3951
  RagableTimeoutError,
3911
3952
  SessionStorageAdapter,
3912
- ShiftClient,
3913
- StorageClient,
3914
3953
  Transport,
3915
3954
  asPostgrestResponse,
3916
3955
  assertPostgrestSuccess,
3917
3956
  bindFetch,
3957
+ buildInferenceRequestBody,
3918
3958
  collectAssistantTextFromUiSegments,
3919
3959
  collectionRecordToRowWithMeta,
3920
3960
  collectionRecordsToRowWithMeta,
3921
3961
  createBrowserClient,
3922
3962
  createClient,
3923
- createRagPipeline,
3924
3963
  createRagableBrowserClient,
3925
- createRagableServerClient,
3964
+ createStreamResultFromParts,
3926
3965
  detectStorage,
3927
3966
  effectiveDataAuth,
3928
3967
  extractErrorMessage,
3929
3968
  finalizeAgentChatUiTurn,
3930
3969
  foldAgentStreamIntoUiSegments,
3931
3970
  formatPostgrestError,
3932
- formatRetrievalContext,
3933
3971
  formatSdkError,
3934
3972
  generateIdempotencyKey,
3935
3973
  isIncompleteAgentStreamError,
3974
+ mapAgentEvent,
3975
+ mapFireworksChunk,
3936
3976
  normalizeBrowserApiBase,
3937
3977
  parseAgentStreamAgentInfo,
3938
3978
  parseAgentStreamDone,