@iota-uz/sdk 0.4.34 → 0.4.35

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.
@@ -12689,7 +12689,9 @@ function ModelSelector() {
12689
12689
  }, [currentModel, models, setModel]);
12690
12690
  React.useEffect(() => {
12691
12691
  const handler = (e) => {
12692
- if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key === "m") {
12692
+ const isModifierPressed = e.metaKey || e.ctrlKey;
12693
+ const isShortcutKey = e.code === "KeyM" || e.key.toLowerCase() === "m";
12694
+ if (isModifierPressed && e.shiftKey && !e.altKey && isShortcutKey) {
12693
12695
  e.preventDefault();
12694
12696
  rotateModel();
12695
12697
  }
@@ -17065,6 +17067,140 @@ function useStreaming2(options = {}) {
17065
17067
  reset
17066
17068
  };
17067
17069
  }
17070
+ var TERMINAL = /* @__PURE__ */ new Set([
17071
+ "completed",
17072
+ "cancelled",
17073
+ "failed"
17074
+ ]);
17075
+ function useActiveRuns(dataSource, options = {}) {
17076
+ const [runs, setRuns] = React.useState({});
17077
+ const [ready, setReady] = React.useState(false);
17078
+ const onErrorRef = React.useRef(options.onError);
17079
+ onErrorRef.current = options.onError;
17080
+ const enabled = options.enabled ?? true;
17081
+ const retainTerminalMs = options.retainTerminalMs ?? 0;
17082
+ const emptyStateTimeoutMs = options.emptyStateTimeoutMs ?? 250;
17083
+ React.useEffect(() => {
17084
+ if (!enabled) {
17085
+ return;
17086
+ }
17087
+ if (!dataSource.subscribeActiveRuns) {
17088
+ return;
17089
+ }
17090
+ const controller = new AbortController();
17091
+ let stagingTimer;
17092
+ const staging = {};
17093
+ let sawSnapshotRow = false;
17094
+ const pendingTerminalTimers = /* @__PURE__ */ new Map();
17095
+ const flushSnapshot = () => {
17096
+ setRuns((prev) => ({ ...prev, ...staging }));
17097
+ setReady(true);
17098
+ stagingTimer = void 0;
17099
+ };
17100
+ const subscription = dataSource.subscribeActiveRuns({
17101
+ signal: controller.signal,
17102
+ onError: (evt) => onErrorRef.current?.(evt),
17103
+ onEvent: (evt) => {
17104
+ if (evt.event === "snapshot") {
17105
+ sawSnapshotRow = true;
17106
+ const pending2 = pendingTerminalTimers.get(evt.sessionId);
17107
+ if (pending2 !== void 0) {
17108
+ clearTimeout(pending2);
17109
+ pendingTerminalTimers.delete(evt.sessionId);
17110
+ }
17111
+ staging[evt.sessionId] = {
17112
+ runId: evt.runId,
17113
+ status: evt.status,
17114
+ updatedAt: evt.updatedAt
17115
+ };
17116
+ if (stagingTimer === void 0) {
17117
+ stagingTimer = setTimeout(flushSnapshot, 16);
17118
+ }
17119
+ return;
17120
+ }
17121
+ if (TERMINAL.has(evt.status)) {
17122
+ if (retainTerminalMs <= 0) {
17123
+ setRuns((prev) => {
17124
+ if (!(evt.sessionId in prev)) {
17125
+ return prev;
17126
+ }
17127
+ const next = { ...prev };
17128
+ delete next[evt.sessionId];
17129
+ return next;
17130
+ });
17131
+ return;
17132
+ }
17133
+ setRuns((prev) => ({
17134
+ ...prev,
17135
+ [evt.sessionId]: {
17136
+ runId: evt.runId,
17137
+ status: evt.status,
17138
+ updatedAt: evt.updatedAt
17139
+ }
17140
+ }));
17141
+ const existing = pendingTerminalTimers.get(evt.sessionId);
17142
+ if (existing !== void 0) {
17143
+ clearTimeout(existing);
17144
+ }
17145
+ const handle = setTimeout(() => {
17146
+ pendingTerminalTimers.delete(evt.sessionId);
17147
+ setRuns((prev) => {
17148
+ if (!(evt.sessionId in prev)) {
17149
+ return prev;
17150
+ }
17151
+ const next = { ...prev };
17152
+ delete next[evt.sessionId];
17153
+ return next;
17154
+ });
17155
+ }, retainTerminalMs);
17156
+ pendingTerminalTimers.set(evt.sessionId, handle);
17157
+ return;
17158
+ }
17159
+ const pending = pendingTerminalTimers.get(evt.sessionId);
17160
+ if (pending !== void 0) {
17161
+ clearTimeout(pending);
17162
+ pendingTerminalTimers.delete(evt.sessionId);
17163
+ }
17164
+ setRuns((prev) => ({
17165
+ ...prev,
17166
+ [evt.sessionId]: {
17167
+ runId: evt.runId,
17168
+ status: evt.status,
17169
+ updatedAt: evt.updatedAt
17170
+ }
17171
+ }));
17172
+ }
17173
+ });
17174
+ subscription?.catch((err) => {
17175
+ if (controller.signal.aborted) {
17176
+ return;
17177
+ }
17178
+ const surface = err instanceof Event ? err : new Event("error");
17179
+ onErrorRef.current?.(surface);
17180
+ });
17181
+ const readyTimeout = setTimeout(() => {
17182
+ if (!sawSnapshotRow) {
17183
+ setReady(true);
17184
+ }
17185
+ }, emptyStateTimeoutMs);
17186
+ return () => {
17187
+ controller.abort();
17188
+ if (stagingTimer !== void 0) {
17189
+ clearTimeout(stagingTimer);
17190
+ }
17191
+ clearTimeout(readyTimeout);
17192
+ for (const handle of pendingTerminalTimers.values()) {
17193
+ clearTimeout(handle);
17194
+ }
17195
+ pendingTerminalTimers.clear();
17196
+ };
17197
+ }, [dataSource, enabled, retainTerminalMs, emptyStateTimeoutMs]);
17198
+ const status = React.useCallback(
17199
+ (sessionId) => runs[sessionId]?.status,
17200
+ [runs]
17201
+ );
17202
+ return { runs, ready, status };
17203
+ }
17068
17204
 
17069
17205
  // ui/src/bichat/index.ts
17070
17206
  init_useTranslation();
@@ -19134,6 +19270,8 @@ function toStreamEvent(chunk) {
19134
19270
  return chunk.sessionId ? { type: "user_message", sessionId: chunk.sessionId } : null;
19135
19271
  case "interrupt":
19136
19272
  return chunk.interrupt ? { type: "interrupt", interrupt: chunk.interrupt, sessionId: chunk.sessionId } : null;
19273
+ case "text_block_end":
19274
+ return { type: "text_block_end", seq: chunk.textBlockSeq ?? 0 };
19137
19275
  case "done":
19138
19276
  return { type: "done", sessionId: chunk.sessionId, generationMs: chunk.generationMs };
19139
19277
  case "error":
@@ -19143,6 +19281,90 @@ function toStreamEvent(chunk) {
19143
19281
  }
19144
19282
  }
19145
19283
 
19284
+ // ui/src/bichat/utils/eventNames.ts
19285
+ var STREAM_EVENT_TYPES = [
19286
+ "chunk",
19287
+ "content",
19288
+ "thinking",
19289
+ "tool_start",
19290
+ "tool_end",
19291
+ "text_block_end",
19292
+ "snapshot",
19293
+ "interrupt",
19294
+ "citation",
19295
+ "usage",
19296
+ "ping",
19297
+ "stream_started",
19298
+ "done",
19299
+ "cancelled",
19300
+ "error",
19301
+ "failed"
19302
+ ];
19303
+ var TERMINAL_STREAM_EVENT_TYPES = [
19304
+ "done",
19305
+ "cancelled",
19306
+ "error",
19307
+ "failed"
19308
+ ];
19309
+ function isTerminalEvent(name) {
19310
+ return TERMINAL_STREAM_EVENT_TYPES.includes(name);
19311
+ }
19312
+
19313
+ // ui/src/bichat/data/openManagedEventSource.ts
19314
+ function openManagedEventSource(opts) {
19315
+ const graceMs = opts.connectGraceMs ?? 500;
19316
+ return new Promise((resolve, reject) => {
19317
+ const startedAt = Date.now();
19318
+ const es = new EventSource(opts.url, {
19319
+ withCredentials: opts.withCredentials ?? true
19320
+ });
19321
+ let settled = false;
19322
+ let sawEvent = false;
19323
+ const settle = (err) => {
19324
+ if (settled) {
19325
+ return;
19326
+ }
19327
+ settled = true;
19328
+ es.close();
19329
+ if (err) {
19330
+ reject(err);
19331
+ } else {
19332
+ resolve();
19333
+ }
19334
+ };
19335
+ if (opts.signal) {
19336
+ if (opts.signal.aborted) {
19337
+ settle();
19338
+ return;
19339
+ }
19340
+ opts.signal.addEventListener("abort", () => settle(), { once: true });
19341
+ }
19342
+ const forward = (name) => (evt) => {
19343
+ sawEvent = true;
19344
+ let parsed;
19345
+ try {
19346
+ parsed = JSON.parse(evt.data);
19347
+ } catch {
19348
+ parsed = { __unparseable: true, raw: String(evt.data) };
19349
+ }
19350
+ try {
19351
+ opts.onMessage(name, parsed);
19352
+ } catch {
19353
+ }
19354
+ };
19355
+ for (const name of opts.events) {
19356
+ es.addEventListener(name, forward(name));
19357
+ }
19358
+ es.onerror = (evt) => {
19359
+ opts.onError?.(evt);
19360
+ if (graceMs > 0 && !sawEvent && Date.now() - startedAt < graceMs) {
19361
+ const err = opts.onConnectError ? opts.onConnectError(evt) : new Error("EventSource failed to connect before first event");
19362
+ settle(err);
19363
+ }
19364
+ };
19365
+ });
19366
+ }
19367
+
19146
19368
  // ui/src/bichat/data/AttachmentUploader.ts
19147
19369
  init_chartSpec();
19148
19370
  var MIME_TO_EXTENSION = {
@@ -19397,6 +19619,26 @@ async function ensureAttachmentUpload(attachment, context, uploadFileFn) {
19397
19619
  }
19398
19620
 
19399
19621
  // ui/src/bichat/data/MessageTransport.ts
19622
+ var RunEventsConnectError = class extends Error {
19623
+ constructor(message, cause) {
19624
+ super(message);
19625
+ this.name = "RunEventsConnectError";
19626
+ this.cause = cause;
19627
+ }
19628
+ };
19629
+ function generateRequestId() {
19630
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
19631
+ return crypto.randomUUID();
19632
+ }
19633
+ const bytes = new Uint8Array(16);
19634
+ for (let i = 0; i < bytes.length; i++) {
19635
+ bytes[i] = Math.floor(Math.random() * 256);
19636
+ }
19637
+ bytes[6] = bytes[6] & 15 | 64;
19638
+ bytes[8] = bytes[8] & 63 | 128;
19639
+ const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
19640
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
19641
+ }
19400
19642
  async function* sendMessage(deps, sessionId, content, attachments = [], signal, options) {
19401
19643
  const abortController = new AbortController();
19402
19644
  let onExternalAbort;
@@ -19424,12 +19666,14 @@ async function* sendMessage(deps, sessionId, content, attachments = [], signal,
19424
19666
  sessionId,
19425
19667
  attachmentCount: streamAttachments.length
19426
19668
  });
19669
+ const requestId = options?.requestId ?? generateRequestId();
19427
19670
  const payload = {
19428
19671
  sessionId,
19429
19672
  content,
19430
19673
  debugMode: options?.debugMode ?? false,
19431
19674
  replaceFromMessageId: options?.replaceFromMessageID,
19432
- attachments: streamAttachments
19675
+ attachments: streamAttachments,
19676
+ requestId
19433
19677
  };
19434
19678
  if (options?.reasoningEffort) {
19435
19679
  payload.reasoningEffort = options.reasoningEffort;
@@ -19597,6 +19841,67 @@ async function resumeStream(deps, sessionId, runId, onChunk, signal) {
19597
19841
  }
19598
19842
  }
19599
19843
  }
19844
+ function subscribeRunEvents(deps, sessionId, runId, options) {
19845
+ const base = buildStreamUrl(deps, "/events");
19846
+ const qs = new URLSearchParams({ sessionId, runId });
19847
+ const url = `${base}?${qs.toString()}`;
19848
+ const withCursor = options.lastEventId ? `${url}&${new URLSearchParams({ lastEventId: options.lastEventId }).toString()}` : url;
19849
+ const settleController = new AbortController();
19850
+ if (options.signal) {
19851
+ if (options.signal.aborted) {
19852
+ settleController.abort();
19853
+ } else {
19854
+ options.signal.addEventListener("abort", () => settleController.abort(), {
19855
+ once: true
19856
+ });
19857
+ }
19858
+ }
19859
+ return openManagedEventSource({
19860
+ url: withCursor,
19861
+ events: STREAM_EVENT_TYPES,
19862
+ withCredentials: true,
19863
+ signal: settleController.signal,
19864
+ onError: options.onError,
19865
+ onConnectError: (evt) => new RunEventsConnectError(
19866
+ "EventSource failed to connect before first event",
19867
+ evt
19868
+ ),
19869
+ onMessage: (name, data) => {
19870
+ if (typeof data === "object" && data !== null && data.__unparseable) {
19871
+ options.onChunk({
19872
+ type: "error",
19873
+ error: `Failed to parse event: ${data.raw}`
19874
+ });
19875
+ return;
19876
+ }
19877
+ const parsed = data;
19878
+ if (!parsed.type) {
19879
+ parsed.type = name;
19880
+ }
19881
+ options.onChunk(parsed);
19882
+ if (isTerminalEvent(name) || isTerminalEvent(String(parsed.type))) {
19883
+ settleController.abort();
19884
+ }
19885
+ }
19886
+ });
19887
+ }
19888
+ function subscribeActiveRuns(deps, options) {
19889
+ const url = buildStreamUrl(deps, "/active-runs");
19890
+ return openManagedEventSource({
19891
+ url,
19892
+ events: ["snapshot", "update"],
19893
+ withCredentials: true,
19894
+ signal: options.signal,
19895
+ onError: options.onError,
19896
+ onMessage: (name, data) => {
19897
+ if (typeof data !== "object" || data === null || data.__unparseable) {
19898
+ return;
19899
+ }
19900
+ const body = data;
19901
+ options.onEvent({ event: name, ...body });
19902
+ }
19903
+ });
19904
+ }
19600
19905
  async function submitQuestionAnswers(callRPC, sessionId, questionId, answers) {
19601
19906
  try {
19602
19907
  const flatAnswers = {};
@@ -19865,6 +20170,39 @@ var HttpDataSource = class {
19865
20170
  signal
19866
20171
  );
19867
20172
  }
20173
+ /**
20174
+ * Open a native EventSource against GET /stream/events for the given
20175
+ * run. Used by components that want browser-native auto-reconnect
20176
+ * with Last-Event-ID (tab close, wifi drop, device switch). Prefer
20177
+ * over resumeStream when tailing an already-running generation that
20178
+ * another tab started.
20179
+ */
20180
+ subscribeRunEvents(sessionId, runId, options) {
20181
+ return subscribeRunEvents(
20182
+ {
20183
+ baseUrl: this.config.baseUrl,
20184
+ streamEndpoint: this.config.streamEndpoint
20185
+ },
20186
+ sessionId,
20187
+ runId,
20188
+ options
20189
+ );
20190
+ }
20191
+ /**
20192
+ * Subscribe to the per-tenant active-run fan-out
20193
+ * (GET /stream/active-runs). Never resolves until the caller aborts
20194
+ * via the signal; use from a top-level component (sidebar container)
20195
+ * that mounts for the lifetime of the chat app.
20196
+ */
20197
+ subscribeActiveRuns(options) {
20198
+ return subscribeActiveRuns(
20199
+ {
20200
+ baseUrl: this.config.baseUrl,
20201
+ streamEndpoint: this.config.streamEndpoint
20202
+ },
20203
+ options
20204
+ );
20205
+ }
19868
20206
  async *sendMessage(sessionId, content, attachments = [], signal, options) {
19869
20207
  this.abortController = new AbortController();
19870
20208
  let onExternalAbort;
@@ -19938,6 +20276,50 @@ function createHttpDataSource(config) {
19938
20276
  return new HttpDataSource(config);
19939
20277
  }
19940
20278
 
20279
+ // ui/src/bichat/utils/textBlocks.ts
20280
+ function splitIntoTextBlocks(content, offsets) {
20281
+ if (!content) {
20282
+ return [];
20283
+ }
20284
+ if (!offsets || offsets.length === 0) {
20285
+ return [{ seq: 0, content }];
20286
+ }
20287
+ const sanitized = [...offsets].map((n) => Math.max(0, Math.min(Math.floor(n), content.length))).sort((a, b) => a - b);
20288
+ const blocks = [];
20289
+ let cursor = 0;
20290
+ for (let i = 0; i < sanitized.length; i++) {
20291
+ const end = sanitized[i];
20292
+ if (end <= cursor) {
20293
+ continue;
20294
+ }
20295
+ const slice = content.slice(cursor, end);
20296
+ if (slice) {
20297
+ blocks.push({ seq: blocks.length, content: slice });
20298
+ }
20299
+ cursor = end;
20300
+ }
20301
+ if (cursor < content.length) {
20302
+ blocks.push({ seq: blocks.length, content: content.slice(cursor) });
20303
+ }
20304
+ return blocks;
20305
+ }
20306
+ function readTextBlockOffsets(partialMetadata) {
20307
+ if (!partialMetadata) {
20308
+ return [];
20309
+ }
20310
+ const raw = partialMetadata["text_block_offsets"];
20311
+ if (!Array.isArray(raw)) {
20312
+ return [];
20313
+ }
20314
+ const out = [];
20315
+ for (const entry of raw) {
20316
+ if (typeof entry === "number" && Number.isFinite(entry) && entry >= 0) {
20317
+ out.push(Math.floor(entry));
20318
+ }
20319
+ }
20320
+ return out;
20321
+ }
20322
+
19941
20323
  exports.ATTACHMENT_ACCEPT_ATTRIBUTE = ATTACHMENT_ACCEPT_ATTRIBUTE;
19942
20324
  exports.ActionButton = ActionButton;
19943
20325
  exports.ActivityTrace = ActivityTrace;
@@ -19989,6 +20371,8 @@ exports.QuestionForm = QuestionForm;
19989
20371
  exports.QuestionStep = QuestionStep;
19990
20372
  exports.RateLimiter = RateLimiter;
19991
20373
  exports.RetryActionArea = RetryActionArea;
20374
+ exports.RunEventsConnectError = RunEventsConnectError;
20375
+ exports.STREAM_EVENT_TYPES = STREAM_EVENT_TYPES;
19992
20376
  exports.ScreenReaderAnnouncer = ScreenReaderAnnouncer;
19993
20377
  exports.ScrollToBottomButton = ScrollToBottomButton;
19994
20378
  exports.SearchInput = MemoizedSearchInput;
@@ -20010,6 +20394,7 @@ exports.SourcesPanel = SourcesPanel;
20010
20394
  exports.StreamError = StreamError;
20011
20395
  exports.StreamingCursor = StreamingCursor;
20012
20396
  exports.SystemMessage = SystemMessage;
20397
+ exports.TERMINAL_STREAM_EVENT_TYPES = TERMINAL_STREAM_EVENT_TYPES;
20013
20398
  exports.TabbedChartGroup = TabbedChartGroup;
20014
20399
  exports.TabbedTableGroup = TabbedTableGroup;
20015
20400
  exports.ThemeProvider = ThemeProvider;
@@ -20047,6 +20432,7 @@ exports.groupSteps = groupSteps;
20047
20432
  exports.hasPermission = hasPermission;
20048
20433
  exports.isImageMimeType = isImageMimeType;
20049
20434
  exports.isPermissionDeniedError = isPermissionDeniedError;
20435
+ exports.isTerminalEvent = isTerminalEvent;
20050
20436
  exports.lightTheme = lightTheme;
20051
20437
  exports.listItemVariants = listItemVariants;
20052
20438
  exports.messageContainerVariants = messageContainerVariants;
@@ -20054,12 +20440,15 @@ exports.messageVariants = messageVariants;
20054
20440
  exports.parseBichatStream = parseBichatStream;
20055
20441
  exports.parseBichatStreamEvents = parseBichatStreamEvents;
20056
20442
  exports.parseSSEStream = parseSSEStream;
20443
+ exports.readTextBlockOffsets = readTextBlockOffsets;
20057
20444
  exports.scaleFadeVariants = scaleFadeVariants;
20058
20445
  exports.sessionItemVariants = sessionItemVariants;
20446
+ exports.splitIntoTextBlocks = splitIntoTextBlocks;
20059
20447
  exports.staggerContainerVariants = staggerContainerVariants;
20060
20448
  exports.toErrorDisplay = toErrorDisplay;
20061
20449
  exports.typingDotVariants = typingDotVariants;
20062
20450
  exports.useActionButtonContext = useActionButtonContext;
20451
+ exports.useActiveRuns = useActiveRuns;
20063
20452
  exports.useAttachments = useAttachments;
20064
20453
  exports.useAutoScroll = useAutoScroll;
20065
20454
  exports.useAvatarContext = useAvatarContext;