@ragable/sdk 0.6.22 → 0.6.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +309 -4
- package/dist/index.d.ts +309 -4
- package/dist/index.js +544 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +534 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -10,6 +10,10 @@ function bindFetch(custom) {
|
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
12
|
var DEFAULT_RAGABLE_API_BASE = "https://ragable-341305259977.asia-southeast1.run.app/api";
|
|
13
|
+
function resolveRagableApiBase(explicitBaseUrl) {
|
|
14
|
+
const raw = typeof explicitBaseUrl === "string" && explicitBaseUrl.trim().length > 0 ? explicitBaseUrl.trim() : DEFAULT_RAGABLE_API_BASE.trim();
|
|
15
|
+
return raw.replace(/\/+$/, "");
|
|
16
|
+
}
|
|
13
17
|
var RagableSdkError = class extends Error {
|
|
14
18
|
constructor(message) {
|
|
15
19
|
super(message);
|
|
@@ -138,7 +142,7 @@ var RagableRequestClient = class {
|
|
|
138
142
|
__publicField(this, "fetchImpl");
|
|
139
143
|
__publicField(this, "defaultHeaders");
|
|
140
144
|
this.apiKey = options.apiKey;
|
|
141
|
-
this.baseUrl =
|
|
145
|
+
this.baseUrl = resolveRagableApiBase(options.baseUrl);
|
|
142
146
|
this.fetchImpl = bindFetch(options.fetch);
|
|
143
147
|
this.defaultHeaders = options.headers;
|
|
144
148
|
}
|
|
@@ -327,6 +331,442 @@ function toArrayBuffer(value) {
|
|
|
327
331
|
return copy.buffer;
|
|
328
332
|
}
|
|
329
333
|
|
|
334
|
+
// src/agent-stream.ts
|
|
335
|
+
function assertAborted(signal) {
|
|
336
|
+
if (signal?.aborted) {
|
|
337
|
+
throw new RagableAbortError();
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
function asString(v, fallback = "") {
|
|
341
|
+
return typeof v === "string" ? v : fallback;
|
|
342
|
+
}
|
|
343
|
+
function asNumber(v, fallback = 0) {
|
|
344
|
+
return typeof v === "number" && Number.isFinite(v) ? v : fallback;
|
|
345
|
+
}
|
|
346
|
+
function asUnknownArray(v) {
|
|
347
|
+
return Array.isArray(v) ? v : [];
|
|
348
|
+
}
|
|
349
|
+
function parseAgentStreamDone(e) {
|
|
350
|
+
if (e.type !== "done") return null;
|
|
351
|
+
return {
|
|
352
|
+
response: asString(e["response"]),
|
|
353
|
+
traces: asUnknownArray(e["traces"]),
|
|
354
|
+
totalDurationMs: asNumber(e["totalDurationMs"]),
|
|
355
|
+
...e["httpResponse"] !== void 0 ? { httpResponse: e["httpResponse"] } : {},
|
|
356
|
+
...typeof e["inputTokens"] === "number" ? { inputTokens: e["inputTokens"] } : {},
|
|
357
|
+
...typeof e["outputTokens"] === "number" ? { outputTokens: e["outputTokens"] } : {},
|
|
358
|
+
...typeof e["cachedPromptTokens"] === "number" ? { cachedPromptTokens: e["cachedPromptTokens"] } : {},
|
|
359
|
+
...typeof e["cacheCreationInputTokens"] === "number" ? { cacheCreationInputTokens: e["cacheCreationInputTokens"] } : {},
|
|
360
|
+
...Array.isArray(e["completionProviders"]) ? {
|
|
361
|
+
completionProviders: e["completionProviders"].map((x) => String(x))
|
|
362
|
+
} : {},
|
|
363
|
+
...typeof e["creditsCharged"] === "number" ? { creditsCharged: e["creditsCharged"] } : {},
|
|
364
|
+
...typeof e["agentSteps"] === "number" ? { agentSteps: e["agentSteps"] } : {},
|
|
365
|
+
...e["finishReason"] !== void 0 ? { finishReason: e["finishReason"] } : {},
|
|
366
|
+
...e["stopReason"] !== void 0 ? { stopReason: e["stopReason"] } : {},
|
|
367
|
+
...e["turnMessages"] !== void 0 ? { turnMessages: e["turnMessages"] } : {},
|
|
368
|
+
...typeof e["promptTokensEstimated"] === "number" ? { promptTokensEstimated: e["promptTokensEstimated"] } : {},
|
|
369
|
+
...typeof e["contextWindow"] === "number" ? { contextWindow: e["contextWindow"] } : {}
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
function parseAgentStreamAgentInfo(e) {
|
|
373
|
+
if (e.type !== "agent:info") return null;
|
|
374
|
+
return {
|
|
375
|
+
type: "agent:info",
|
|
376
|
+
name: asString(e["name"]),
|
|
377
|
+
agent_name: asString(e["agent_name"])
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
function parseAgentInfo(e) {
|
|
381
|
+
return parseAgentStreamAgentInfo(e);
|
|
382
|
+
}
|
|
383
|
+
async function runAgentChatStream(source, handlers = {}, options = {}) {
|
|
384
|
+
const { signal } = options;
|
|
385
|
+
let assistantText = "";
|
|
386
|
+
let reasoningText = "";
|
|
387
|
+
let donePayload = null;
|
|
388
|
+
try {
|
|
389
|
+
for await (const event of source) {
|
|
390
|
+
assertAborted(signal);
|
|
391
|
+
handlers.onEvent?.(event);
|
|
392
|
+
const info = parseAgentInfo(event);
|
|
393
|
+
if (info) {
|
|
394
|
+
handlers.onAgentInfo?.(info);
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
switch (event.type) {
|
|
398
|
+
case "ping":
|
|
399
|
+
handlers.onPing?.();
|
|
400
|
+
break;
|
|
401
|
+
case "token": {
|
|
402
|
+
const nodeId = asString(event["nodeId"], "__self__");
|
|
403
|
+
const token = asString(event["token"]);
|
|
404
|
+
assistantText += token;
|
|
405
|
+
handlers.onToken?.(token, { nodeId });
|
|
406
|
+
break;
|
|
407
|
+
}
|
|
408
|
+
case "reasoning_token": {
|
|
409
|
+
const nodeId = asString(event["nodeId"], "__self__");
|
|
410
|
+
const token = asString(event["token"]);
|
|
411
|
+
reasoningText += token;
|
|
412
|
+
handlers.onReasoningToken?.(token, { nodeId });
|
|
413
|
+
break;
|
|
414
|
+
}
|
|
415
|
+
case "tool:call":
|
|
416
|
+
handlers.onToolCall?.({
|
|
417
|
+
nodeId: asString(event["nodeId"]),
|
|
418
|
+
toolName: asString(event["toolName"]),
|
|
419
|
+
args: event["args"]
|
|
420
|
+
});
|
|
421
|
+
break;
|
|
422
|
+
case "tool:args_update": {
|
|
423
|
+
const raw = event["args"];
|
|
424
|
+
const args = raw !== null && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
425
|
+
handlers.onToolArgsUpdate?.({
|
|
426
|
+
nodeId: asString(event["nodeId"]),
|
|
427
|
+
args
|
|
428
|
+
});
|
|
429
|
+
break;
|
|
430
|
+
}
|
|
431
|
+
case "tool:result":
|
|
432
|
+
handlers.onToolResult?.({
|
|
433
|
+
nodeId: asString(event["nodeId"]),
|
|
434
|
+
toolName: asString(event["toolName"]),
|
|
435
|
+
durationMs: asNumber(event["durationMs"]),
|
|
436
|
+
...typeof event["result"] === "string" ? { result: event["result"] } : {}
|
|
437
|
+
});
|
|
438
|
+
break;
|
|
439
|
+
case "node:start":
|
|
440
|
+
handlers.onNodeStart?.({
|
|
441
|
+
nodeId: asString(event["nodeId"]),
|
|
442
|
+
nodeType: asString(event["nodeType"]),
|
|
443
|
+
label: asString(event["label"])
|
|
444
|
+
});
|
|
445
|
+
break;
|
|
446
|
+
case "node:complete":
|
|
447
|
+
handlers.onNodeComplete?.({
|
|
448
|
+
nodeId: asString(event["nodeId"]),
|
|
449
|
+
output: event["output"],
|
|
450
|
+
durationMs: asNumber(event["durationMs"])
|
|
451
|
+
});
|
|
452
|
+
break;
|
|
453
|
+
case "node:error":
|
|
454
|
+
handlers.onNodeError?.({
|
|
455
|
+
nodeId: asString(event["nodeId"]),
|
|
456
|
+
error: asString(event["error"])
|
|
457
|
+
});
|
|
458
|
+
break;
|
|
459
|
+
case "done": {
|
|
460
|
+
const parsed = parseAgentStreamDone(event);
|
|
461
|
+
if (parsed) {
|
|
462
|
+
donePayload = parsed;
|
|
463
|
+
handlers.onDone?.(parsed);
|
|
464
|
+
}
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
default:
|
|
468
|
+
break;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
} catch (err) {
|
|
472
|
+
handlers.onError?.(err);
|
|
473
|
+
throw err;
|
|
474
|
+
}
|
|
475
|
+
if (!donePayload) {
|
|
476
|
+
const err = new RagableError(
|
|
477
|
+
"Agent stream ended without a done event",
|
|
478
|
+
502,
|
|
479
|
+
{ code: "SDK_AGENT_STREAM_INCOMPLETE" }
|
|
480
|
+
);
|
|
481
|
+
handlers.onError?.(err);
|
|
482
|
+
throw err;
|
|
483
|
+
}
|
|
484
|
+
const result = {
|
|
485
|
+
...donePayload,
|
|
486
|
+
assistantText,
|
|
487
|
+
reasoningText
|
|
488
|
+
};
|
|
489
|
+
handlers.onComplete?.(result);
|
|
490
|
+
return result;
|
|
491
|
+
}
|
|
492
|
+
async function runAgentChatStreamLenient(source, handlers = {}, options = {}) {
|
|
493
|
+
try {
|
|
494
|
+
return await runAgentChatStream(source, handlers, options);
|
|
495
|
+
} catch (e) {
|
|
496
|
+
if (e instanceof RagableError && e.code === "SDK_AGENT_STREAM_INCOMPLETE") {
|
|
497
|
+
return null;
|
|
498
|
+
}
|
|
499
|
+
throw e;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
function isIncompleteAgentStreamError(e) {
|
|
503
|
+
return e instanceof RagableError && e.code === "SDK_AGENT_STREAM_INCOMPLETE";
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// src/agent-chat-ui.ts
|
|
507
|
+
function asString2(v, fallback = "") {
|
|
508
|
+
return typeof v === "string" ? v : fallback;
|
|
509
|
+
}
|
|
510
|
+
function asNumber2(v, fallback = 0) {
|
|
511
|
+
return typeof v === "number" && Number.isFinite(v) ? v : fallback;
|
|
512
|
+
}
|
|
513
|
+
function assertAborted2(signal) {
|
|
514
|
+
if (signal?.aborted) {
|
|
515
|
+
throw new RagableAbortError();
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
function recordFromUnknown(v) {
|
|
519
|
+
if (v !== null && typeof v === "object" && !Array.isArray(v)) {
|
|
520
|
+
return { ...v };
|
|
521
|
+
}
|
|
522
|
+
return {};
|
|
523
|
+
}
|
|
524
|
+
function lastToolBlocksStream(last) {
|
|
525
|
+
return last?.type === "tool" && last.status === "started";
|
|
526
|
+
}
|
|
527
|
+
function toolSegmentId(event) {
|
|
528
|
+
const nid = event["nodeId"];
|
|
529
|
+
if (typeof nid === "string" && nid.length > 0) return nid;
|
|
530
|
+
const tn = event["toolName"];
|
|
531
|
+
if (typeof tn === "string" && tn.length > 0) return tn;
|
|
532
|
+
return "__tool__";
|
|
533
|
+
}
|
|
534
|
+
function normalizeContextSummarizedMode(m) {
|
|
535
|
+
if (m === "llm" || m === "heuristic" || m === "llm+heuristic" || m === "aggressive") {
|
|
536
|
+
return m;
|
|
537
|
+
}
|
|
538
|
+
return void 0;
|
|
539
|
+
}
|
|
540
|
+
function normalizeContextSummarizedReason(r) {
|
|
541
|
+
if (r === "soft_limit" || r === "forced") return r;
|
|
542
|
+
return void 0;
|
|
543
|
+
}
|
|
544
|
+
function foldContextSummarized(prev, event) {
|
|
545
|
+
const step = asNumber2(event["step"], 0);
|
|
546
|
+
const mode = normalizeContextSummarizedMode(event["mode"]);
|
|
547
|
+
const reason = normalizeContextSummarizedReason(event["reason"]);
|
|
548
|
+
const tro = event["tokensRemovedEstimate"];
|
|
549
|
+
const eta = event["estimatedTokensAfter"];
|
|
550
|
+
return [
|
|
551
|
+
...prev,
|
|
552
|
+
{
|
|
553
|
+
type: "context_summarized",
|
|
554
|
+
step,
|
|
555
|
+
...mode ? { mode } : {},
|
|
556
|
+
...reason ? { reason } : {},
|
|
557
|
+
...typeof tro === "number" && tro > 0 ? { tokensRemovedEstimate: tro } : {},
|
|
558
|
+
...typeof eta === "number" && eta > 0 ? { estimatedTokensAfter: eta } : {}
|
|
559
|
+
}
|
|
560
|
+
];
|
|
561
|
+
}
|
|
562
|
+
function collectAssistantTextFromUiSegments(segments) {
|
|
563
|
+
return segments.filter((s) => s.type === "text").map((s) => s.content).join("");
|
|
564
|
+
}
|
|
565
|
+
function foldAgentStreamIntoUiSegments(prev, event) {
|
|
566
|
+
switch (event.type) {
|
|
567
|
+
case "token": {
|
|
568
|
+
const last = prev[prev.length - 1];
|
|
569
|
+
if (lastToolBlocksStream(last)) return prev;
|
|
570
|
+
const token = asString2(event["token"]);
|
|
571
|
+
if (!token) return prev;
|
|
572
|
+
if (last?.type === "text") {
|
|
573
|
+
return [
|
|
574
|
+
...prev.slice(0, -1),
|
|
575
|
+
{ type: "text", content: last.content + token }
|
|
576
|
+
];
|
|
577
|
+
}
|
|
578
|
+
return [...prev, { type: "text", content: token }];
|
|
579
|
+
}
|
|
580
|
+
case "reasoning_token": {
|
|
581
|
+
const last = prev[prev.length - 1];
|
|
582
|
+
if (lastToolBlocksStream(last)) return prev;
|
|
583
|
+
const token = asString2(event["token"]);
|
|
584
|
+
if (!token) return prev;
|
|
585
|
+
if (last?.type === "reasoning") {
|
|
586
|
+
return [
|
|
587
|
+
...prev.slice(0, -1),
|
|
588
|
+
{ type: "reasoning", content: last.content + token }
|
|
589
|
+
];
|
|
590
|
+
}
|
|
591
|
+
return [...prev, { type: "reasoning", content: token }];
|
|
592
|
+
}
|
|
593
|
+
case "tool:call": {
|
|
594
|
+
const id = toolSegmentId(event);
|
|
595
|
+
const toolName = asString2(event["toolName"], "tool");
|
|
596
|
+
const argsRaw = event["args"];
|
|
597
|
+
const args = argsRaw !== null && typeof argsRaw === "object" && !Array.isArray(argsRaw) ? argsRaw : void 0;
|
|
598
|
+
return [
|
|
599
|
+
...prev,
|
|
600
|
+
{
|
|
601
|
+
type: "tool",
|
|
602
|
+
id,
|
|
603
|
+
toolName,
|
|
604
|
+
status: "started",
|
|
605
|
+
...args !== void 0 ? { args } : {}
|
|
606
|
+
}
|
|
607
|
+
];
|
|
608
|
+
}
|
|
609
|
+
case "tool:args_update": {
|
|
610
|
+
const nodeId = asString2(event["nodeId"]);
|
|
611
|
+
const patch = recordFromUnknown(event["args"]);
|
|
612
|
+
return prev.map((seg) => {
|
|
613
|
+
if (seg.type !== "tool" || seg.id !== nodeId) return seg;
|
|
614
|
+
const merged = { ...recordFromUnknown(seg.args), ...patch };
|
|
615
|
+
return {
|
|
616
|
+
...seg,
|
|
617
|
+
args: merged
|
|
618
|
+
};
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
case "tool:result": {
|
|
622
|
+
const nodeId = asString2(event["nodeId"]);
|
|
623
|
+
const toolName = asString2(event["toolName"]) || asString2(event["nodeId"]);
|
|
624
|
+
const durationMs = typeof event["durationMs"] === "number" ? event["durationMs"] : void 0;
|
|
625
|
+
const resultStr = typeof event["result"] === "string" ? event["result"] : void 0;
|
|
626
|
+
let idx = -1;
|
|
627
|
+
if (nodeId) {
|
|
628
|
+
for (let i = prev.length - 1; i >= 0; i--) {
|
|
629
|
+
const s = prev[i];
|
|
630
|
+
if (s.type === "tool" && s.status === "started" && s.id === nodeId) {
|
|
631
|
+
idx = i;
|
|
632
|
+
break;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
if (idx < 0 && toolName) {
|
|
637
|
+
for (let i = prev.length - 1; i >= 0; i--) {
|
|
638
|
+
const s = prev[i];
|
|
639
|
+
if (s.type === "tool" && s.status === "started" && s.toolName === toolName) {
|
|
640
|
+
idx = i;
|
|
641
|
+
break;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
if (idx < 0) return prev;
|
|
646
|
+
const next = [...prev];
|
|
647
|
+
const seg = next[idx];
|
|
648
|
+
if (seg.type !== "tool") return prev;
|
|
649
|
+
next[idx] = {
|
|
650
|
+
...seg,
|
|
651
|
+
status: "completed",
|
|
652
|
+
...durationMs !== void 0 ? { durationMs } : {},
|
|
653
|
+
...resultStr !== void 0 ? { result: resultStr } : {}
|
|
654
|
+
};
|
|
655
|
+
return next;
|
|
656
|
+
}
|
|
657
|
+
case "context_summarized":
|
|
658
|
+
return foldContextSummarized(prev, event);
|
|
659
|
+
case "llm_step": {
|
|
660
|
+
return [
|
|
661
|
+
...prev,
|
|
662
|
+
{
|
|
663
|
+
type: "llm_step",
|
|
664
|
+
step: Number(event["step"]),
|
|
665
|
+
inputTokens: Number(event["inputTokens"] ?? 0),
|
|
666
|
+
outputTokens: Number(event["outputTokens"] ?? 0),
|
|
667
|
+
...typeof event["cachedPromptTokens"] === "number" ? { cachedPromptTokens: event["cachedPromptTokens"] } : {},
|
|
668
|
+
...typeof event["cacheCreationInputTokens"] === "number" ? { cacheCreationInputTokens: event["cacheCreationInputTokens"] } : {},
|
|
669
|
+
creditsEstimated: Number(event["creditsEstimated"] ?? 0),
|
|
670
|
+
...typeof event["apiCostUsd"] === "number" && Number.isFinite(event["apiCostUsd"]) ? { apiCostUsd: event["apiCostUsd"] } : {},
|
|
671
|
+
...typeof event["provider"] === "string" && event["provider"] ? { provider: event["provider"] } : {}
|
|
672
|
+
}
|
|
673
|
+
];
|
|
674
|
+
}
|
|
675
|
+
default:
|
|
676
|
+
return prev;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
function finalizeAgentChatUiTurn(segments, done) {
|
|
680
|
+
let segs = segments.length > 0 ? [...segments] : void 0;
|
|
681
|
+
if (done.stopReason) {
|
|
682
|
+
const stopSeg = {
|
|
683
|
+
type: "stop_reason",
|
|
684
|
+
content: done.stopReason,
|
|
685
|
+
finishReason: done.finishReason ?? "error"
|
|
686
|
+
};
|
|
687
|
+
segs = segs ? [...segs, stopSeg] : [stopSeg];
|
|
688
|
+
}
|
|
689
|
+
const fromText = segs ? collectAssistantTextFromUiSegments(segs) : "";
|
|
690
|
+
const content = done.response || fromText || "No response.";
|
|
691
|
+
const message = {
|
|
692
|
+
role: "ai",
|
|
693
|
+
content,
|
|
694
|
+
...segs && segs.length > 0 ? { segments: segs } : {},
|
|
695
|
+
finishReason: done.finishReason ?? null,
|
|
696
|
+
...Array.isArray(done.completionProviders) && done.completionProviders.length > 0 ? { completionProviders: done.completionProviders } : {},
|
|
697
|
+
...typeof done.agentSteps === "number" && Number.isFinite(done.agentSteps) && done.agentSteps > 0 ? { agentSteps: Math.floor(done.agentSteps) } : {},
|
|
698
|
+
usage: {
|
|
699
|
+
inputTokens: done.inputTokens ?? 0,
|
|
700
|
+
outputTokens: done.outputTokens ?? 0,
|
|
701
|
+
creditsCharged: done.creditsCharged ?? 0,
|
|
702
|
+
...typeof done.cachedPromptTokens === "number" && done.cachedPromptTokens > 0 ? { cachedPromptTokens: done.cachedPromptTokens } : {},
|
|
703
|
+
...typeof done.cacheCreationInputTokens === "number" && done.cacheCreationInputTokens > 0 ? { cacheCreationInputTokens: done.cacheCreationInputTokens } : {}
|
|
704
|
+
},
|
|
705
|
+
...typeof done.totalDurationMs === "number" && done.totalDurationMs > 0 ? { durationMs: done.totalDurationMs } : {}
|
|
706
|
+
};
|
|
707
|
+
return { segments: segs ?? [], message };
|
|
708
|
+
}
|
|
709
|
+
async function runAgentChatStreamForUi(source, handlers = {}, options = {}) {
|
|
710
|
+
const { signal } = options;
|
|
711
|
+
let segments = [];
|
|
712
|
+
let donePayload = null;
|
|
713
|
+
try {
|
|
714
|
+
for await (const event of source) {
|
|
715
|
+
assertAborted2(signal);
|
|
716
|
+
handlers.onEvent?.(event);
|
|
717
|
+
const info = parseAgentStreamAgentInfo(event);
|
|
718
|
+
if (info) {
|
|
719
|
+
handlers.onAgentInfo?.(info);
|
|
720
|
+
continue;
|
|
721
|
+
}
|
|
722
|
+
if (event.type === "ping") continue;
|
|
723
|
+
if (event.type === "done") {
|
|
724
|
+
const parsed = parseAgentStreamDone(event);
|
|
725
|
+
if (parsed) {
|
|
726
|
+
donePayload = parsed;
|
|
727
|
+
handlers.onDone?.(parsed);
|
|
728
|
+
}
|
|
729
|
+
break;
|
|
730
|
+
}
|
|
731
|
+
const next = foldAgentStreamIntoUiSegments(segments, event);
|
|
732
|
+
if (next !== segments) {
|
|
733
|
+
segments = next;
|
|
734
|
+
handlers.onSegments?.(segments);
|
|
735
|
+
if (event.type === "token") {
|
|
736
|
+
handlers.onStreamingText?.(
|
|
737
|
+
collectAssistantTextFromUiSegments(segments)
|
|
738
|
+
);
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
} catch (err) {
|
|
743
|
+
handlers.onError?.(err);
|
|
744
|
+
throw err;
|
|
745
|
+
}
|
|
746
|
+
if (!donePayload) {
|
|
747
|
+
const err = new RagableError(
|
|
748
|
+
"Agent stream ended without a done event",
|
|
749
|
+
502,
|
|
750
|
+
{ code: "SDK_AGENT_STREAM_INCOMPLETE" }
|
|
751
|
+
);
|
|
752
|
+
handlers.onError?.(err);
|
|
753
|
+
throw err;
|
|
754
|
+
}
|
|
755
|
+
const segmentsMidTurn = [...segments];
|
|
756
|
+
const { segments: finalSegs, message } = finalizeAgentChatUiTurn(
|
|
757
|
+
segments,
|
|
758
|
+
donePayload
|
|
759
|
+
);
|
|
760
|
+
const result = {
|
|
761
|
+
segmentsMidTurn,
|
|
762
|
+
segments: finalSegs,
|
|
763
|
+
message,
|
|
764
|
+
done: donePayload
|
|
765
|
+
};
|
|
766
|
+
handlers.onComplete?.(result);
|
|
767
|
+
return result;
|
|
768
|
+
}
|
|
769
|
+
|
|
330
770
|
// src/sse.ts
|
|
331
771
|
async function parseMaybeJsonBody(response) {
|
|
332
772
|
const contentType = response.headers.get("content-type") ?? "";
|
|
@@ -426,7 +866,8 @@ var AgentsClient = class {
|
|
|
426
866
|
body: {
|
|
427
867
|
message: params.message,
|
|
428
868
|
...params.history !== void 0 ? { history: params.history } : {}
|
|
429
|
-
}
|
|
869
|
+
},
|
|
870
|
+
...params.signal !== void 0 ? { signal: params.signal } : {}
|
|
430
871
|
}
|
|
431
872
|
);
|
|
432
873
|
if (!response.ok) {
|
|
@@ -440,6 +881,24 @@ var AgentsClient = class {
|
|
|
440
881
|
}
|
|
441
882
|
yield* readSseStream(body);
|
|
442
883
|
}
|
|
884
|
+
/**
|
|
885
|
+
* Stream an agent turn with callbacks; returns the final `done` payload plus streamed text.
|
|
886
|
+
* Prefer this over manual iteration when building chat UIs against the server API key client.
|
|
887
|
+
*/
|
|
888
|
+
async runChatStream(agentId, params, handlers = {}) {
|
|
889
|
+
return runAgentChatStream(this.chatStream(agentId, params), handlers, {
|
|
890
|
+
signal: params.signal
|
|
891
|
+
});
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* Stream with dashboard-style `AgentChat` ergonomics: {@link AgentChatStreamUiHandlers.onSegments}
|
|
895
|
+
* / `onStreamingText` for live UI; returns a persisted-shaped assistant message on `done`.
|
|
896
|
+
*/
|
|
897
|
+
async runChatUi(agentId, params, handlers = {}) {
|
|
898
|
+
return runAgentChatStreamForUi(this.chatStream(agentId, params), handlers, {
|
|
899
|
+
signal: params.signal
|
|
900
|
+
});
|
|
901
|
+
}
|
|
443
902
|
};
|
|
444
903
|
|
|
445
904
|
// src/transport.ts
|
|
@@ -1707,7 +2166,7 @@ var RagableAuth = class {
|
|
|
1707
2166
|
__publicField(this, "broadcast", null);
|
|
1708
2167
|
__publicField(this, "visibilityHandler", null);
|
|
1709
2168
|
__publicField(this, "initialized", false);
|
|
1710
|
-
this.baseUrl =
|
|
2169
|
+
this.baseUrl = resolveRagableApiBase(config.baseUrl);
|
|
1711
2170
|
this.authGroupId = config.authGroupId;
|
|
1712
2171
|
this.fetchImpl = bindFetch(config.fetch);
|
|
1713
2172
|
this.defaultHeaders = config.headers;
|
|
@@ -2076,8 +2535,8 @@ function decodeJwtExpiry(jwt) {
|
|
|
2076
2535
|
}
|
|
2077
2536
|
|
|
2078
2537
|
// src/browser.ts
|
|
2079
|
-
function normalizeBrowserApiBase() {
|
|
2080
|
-
return
|
|
2538
|
+
function normalizeBrowserApiBase(explicitBaseUrl) {
|
|
2539
|
+
return resolveRagableApiBase(explicitBaseUrl);
|
|
2081
2540
|
}
|
|
2082
2541
|
function effectiveDataAuth(options) {
|
|
2083
2542
|
if (options.dataAuth) return options.dataAuth;
|
|
@@ -2297,6 +2756,18 @@ var BrowserCollectionApi = class {
|
|
|
2297
2756
|
this.databaseInstanceId
|
|
2298
2757
|
)
|
|
2299
2758
|
));
|
|
2759
|
+
/**
|
|
2760
|
+
* Insert multiple rows in one request (server multi-value `INSERT`, single transaction).
|
|
2761
|
+
* Empty **`items`** resolves to an empty array. Max batch size is enforced on the server (500).
|
|
2762
|
+
*/
|
|
2763
|
+
__publicField(this, "insertMany", (items) => asPostgrestResponse(
|
|
2764
|
+
() => this.database._requestCollection(
|
|
2765
|
+
"POST",
|
|
2766
|
+
`/${encodeURIComponent(this.name)}/records/batch`,
|
|
2767
|
+
{ items },
|
|
2768
|
+
this.databaseInstanceId
|
|
2769
|
+
)
|
|
2770
|
+
));
|
|
2300
2771
|
/**
|
|
2301
2772
|
* Update rows matching `where` (JSON fields, plus envelope `id` / `createdAt` / `updatedAt`).
|
|
2302
2773
|
*/
|
|
@@ -2325,6 +2796,21 @@ var BrowserCollectionApi = class {
|
|
|
2325
2796
|
this.databaseInstanceId
|
|
2326
2797
|
)
|
|
2327
2798
|
));
|
|
2799
|
+
/**
|
|
2800
|
+
* Like {@link BrowserCollectionApi.delete} but the success payload includes **`meta.count`**
|
|
2801
|
+
* (number of deleted rows), matching {@link BrowserCollectionApi.updateMany}.
|
|
2802
|
+
*/
|
|
2803
|
+
__publicField(this, "deleteMany", async (where, options) => {
|
|
2804
|
+
const r = await this.delete(where, options);
|
|
2805
|
+
if (r.error) return r;
|
|
2806
|
+
return {
|
|
2807
|
+
data: {
|
|
2808
|
+
records: r.data.records,
|
|
2809
|
+
meta: { count: r.data.deleted }
|
|
2810
|
+
},
|
|
2811
|
+
error: null
|
|
2812
|
+
};
|
|
2813
|
+
});
|
|
2328
2814
|
}
|
|
2329
2815
|
normalizeFindArgs(whereOrParams) {
|
|
2330
2816
|
const hasQueryKeys = typeof whereOrParams === "object" && whereOrParams !== null && FIND_QUERY_KEYS.some(
|
|
@@ -2341,6 +2827,7 @@ var RagableBrowserDatabaseClient = class {
|
|
|
2341
2827
|
this.options = options;
|
|
2342
2828
|
this.ragableAuth = ragableAuth;
|
|
2343
2829
|
__publicField(this, "fetchImpl");
|
|
2830
|
+
__publicField(this, "apiBase");
|
|
2344
2831
|
__publicField(this, "_transport", null);
|
|
2345
2832
|
__publicField(this, "collections");
|
|
2346
2833
|
__publicField(this, "collection");
|
|
@@ -2364,7 +2851,7 @@ var RagableBrowserDatabaseClient = class {
|
|
|
2364
2851
|
}
|
|
2365
2852
|
const gid = requireAuthGroupId(opts);
|
|
2366
2853
|
const token = await resolveDatabaseAuthBearer(opts, ragableAuth);
|
|
2367
|
-
const apiBase =
|
|
2854
|
+
const apiBase = this.apiBase;
|
|
2368
2855
|
const qs = params.searchParams.toString();
|
|
2369
2856
|
const url = `${apiBase}/auth-groups/${gid}/data/rest/${params.table}${qs ? `?${qs}` : ""}`;
|
|
2370
2857
|
const headers = new Headers(opts.headers);
|
|
@@ -2479,6 +2966,7 @@ var RagableBrowserDatabaseClient = class {
|
|
|
2479
2966
|
)
|
|
2480
2967
|
});
|
|
2481
2968
|
this.fetchImpl = bindFetch(options.fetch);
|
|
2969
|
+
this.apiBase = resolveRagableApiBase(options.baseUrl);
|
|
2482
2970
|
this.collections = new Proxy(
|
|
2483
2971
|
{},
|
|
2484
2972
|
{
|
|
@@ -2500,7 +2988,7 @@ var RagableBrowserDatabaseClient = class {
|
|
|
2500
2988
|
this._transport = transport;
|
|
2501
2989
|
}
|
|
2502
2990
|
toUrl(path) {
|
|
2503
|
-
return `${
|
|
2991
|
+
return `${this.apiBase}${path.startsWith("/") ? path : `/${path}`}`;
|
|
2504
2992
|
}
|
|
2505
2993
|
async _requestCollection(method, path, body, databaseInstanceId) {
|
|
2506
2994
|
const gid = requireAuthGroupId(this.options);
|
|
@@ -2591,7 +3079,7 @@ async function subscribeBrowserRealtime(options, ragableAuth, fetchImpl, params)
|
|
|
2591
3079
|
headers.set("Authorization", `Bearer ${token}`);
|
|
2592
3080
|
headers.set("Content-Type", "application/json");
|
|
2593
3081
|
const response = await fetchImpl(
|
|
2594
|
-
`${
|
|
3082
|
+
`${resolveRagableApiBase(options.baseUrl)}/auth-groups/${gid}/data/realtime/stream`,
|
|
2595
3083
|
{
|
|
2596
3084
|
method: "POST",
|
|
2597
3085
|
headers,
|
|
@@ -2724,10 +3212,12 @@ var RagableBrowserAgentsClient = class {
|
|
|
2724
3212
|
constructor(options) {
|
|
2725
3213
|
this.options = options;
|
|
2726
3214
|
__publicField(this, "fetchImpl");
|
|
3215
|
+
__publicField(this, "apiBase");
|
|
2727
3216
|
this.fetchImpl = bindFetch(options.fetch);
|
|
3217
|
+
this.apiBase = resolveRagableApiBase(options.baseUrl);
|
|
2728
3218
|
}
|
|
2729
3219
|
toUrl(path) {
|
|
2730
|
-
return `${
|
|
3220
|
+
return `${this.apiBase}${path.startsWith("/") ? path : `/${path}`}`;
|
|
2731
3221
|
}
|
|
2732
3222
|
requireWebsiteId() {
|
|
2733
3223
|
const websiteId = this.options.websiteId?.trim();
|
|
@@ -2769,7 +3259,8 @@ var RagableBrowserAgentsClient = class {
|
|
|
2769
3259
|
{
|
|
2770
3260
|
method: "POST",
|
|
2771
3261
|
headers,
|
|
2772
|
-
body: JSON.stringify(body)
|
|
3262
|
+
body: JSON.stringify(body),
|
|
3263
|
+
...params.signal !== void 0 ? { signal: params.signal } : {}
|
|
2773
3264
|
}
|
|
2774
3265
|
);
|
|
2775
3266
|
if (!response.ok) {
|
|
@@ -2798,7 +3289,8 @@ var RagableBrowserAgentsClient = class {
|
|
|
2798
3289
|
body: JSON.stringify({
|
|
2799
3290
|
message: params.message,
|
|
2800
3291
|
...params.history !== void 0 ? { history: params.history } : {}
|
|
2801
|
-
})
|
|
3292
|
+
}),
|
|
3293
|
+
...params.signal !== void 0 ? { signal: params.signal } : {}
|
|
2802
3294
|
}
|
|
2803
3295
|
);
|
|
2804
3296
|
if (!response.ok) {
|
|
@@ -2809,6 +3301,26 @@ var RagableBrowserAgentsClient = class {
|
|
|
2809
3301
|
if (!response.body) return;
|
|
2810
3302
|
yield* readSseStream(response.body);
|
|
2811
3303
|
}
|
|
3304
|
+
/**
|
|
3305
|
+
* Stream a project agent (`/agents/*.json`) with callbacks; returns the final `done` payload
|
|
3306
|
+
* plus streamed assistant text. Prefer this over manual `for await` when building chat UIs.
|
|
3307
|
+
*/
|
|
3308
|
+
async runChatStreamByName(agentName, params, handlers = {}) {
|
|
3309
|
+
return runAgentChatStream(this.chatStreamByName(agentName, params), handlers, {
|
|
3310
|
+
signal: params.signal
|
|
3311
|
+
});
|
|
3312
|
+
}
|
|
3313
|
+
/**
|
|
3314
|
+
* Same as {@link runChatStreamByName} but folds events into `AgentChat`-style segments
|
|
3315
|
+
* (`onSegments` / `onStreamingText`) and returns a history-ready assistant message.
|
|
3316
|
+
*/
|
|
3317
|
+
async runChatUiByName(agentName, params, handlers = {}) {
|
|
3318
|
+
return runAgentChatStreamForUi(
|
|
3319
|
+
this.chatStreamByName(agentName, params),
|
|
3320
|
+
handlers,
|
|
3321
|
+
{ signal: params.signal }
|
|
3322
|
+
);
|
|
3323
|
+
}
|
|
2812
3324
|
createConversation(params) {
|
|
2813
3325
|
const headers = new Headers(this.options.headers);
|
|
2814
3326
|
headers.set("Content-Type", "application/json");
|
|
@@ -2905,6 +3417,7 @@ var RagableBrowser = class {
|
|
|
2905
3417
|
if (options.authGroupId) {
|
|
2906
3418
|
this._ragableAuth = new RagableAuth({
|
|
2907
3419
|
authGroupId: options.authGroupId,
|
|
3420
|
+
baseUrl: options.baseUrl,
|
|
2908
3421
|
fetch: options.fetch,
|
|
2909
3422
|
headers: options.headers,
|
|
2910
3423
|
auth: options.auth
|
|
@@ -3055,6 +3568,7 @@ export {
|
|
|
3055
3568
|
asPostgrestResponse,
|
|
3056
3569
|
assertPostgrestSuccess,
|
|
3057
3570
|
bindFetch,
|
|
3571
|
+
collectAssistantTextFromUiSegments,
|
|
3058
3572
|
collectionRecordToRowWithMeta,
|
|
3059
3573
|
collectionRecordsToRowWithMeta,
|
|
3060
3574
|
createBrowserClient,
|
|
@@ -3065,14 +3579,23 @@ export {
|
|
|
3065
3579
|
detectStorage,
|
|
3066
3580
|
effectiveDataAuth,
|
|
3067
3581
|
extractErrorMessage,
|
|
3582
|
+
finalizeAgentChatUiTurn,
|
|
3583
|
+
foldAgentStreamIntoUiSegments,
|
|
3068
3584
|
formatPostgrestError,
|
|
3069
3585
|
formatRetrievalContext,
|
|
3070
3586
|
formatSdkError,
|
|
3071
3587
|
generateIdempotencyKey,
|
|
3588
|
+
isIncompleteAgentStreamError,
|
|
3072
3589
|
normalizeBrowserApiBase,
|
|
3590
|
+
parseAgentStreamAgentInfo,
|
|
3591
|
+
parseAgentStreamDone,
|
|
3073
3592
|
parseSseDataLine,
|
|
3074
3593
|
parseTransportResponse,
|
|
3075
3594
|
readSseStream,
|
|
3595
|
+
resolveRagableApiBase,
|
|
3596
|
+
runAgentChatStream,
|
|
3597
|
+
runAgentChatStreamForUi,
|
|
3598
|
+
runAgentChatStreamLenient,
|
|
3076
3599
|
toRagableResult,
|
|
3077
3600
|
unwrapPostgrest
|
|
3078
3601
|
};
|