@inkeep/agents-ui 0.15.19 → 0.15.21

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.
@@ -1,82 +1,96 @@
1
1
  "use client";
2
- import { useRef as s, useCallback as E, useEffect as k } from "react";
3
- import { useLocalStorage as D } from "./use-local-storage.js";
4
- import { useInkeepApiClient as F } from "./use-inkeep-api-client.js";
5
- const M = 30 * 1e3, b = 2147483647, L = () => {
6
- }, j = async () => ({});
7
- function w(t) {
8
- return new Date(t.expiresAt).getTime() - M <= Date.now();
2
+ import { useRef as o, useEffect as l, useCallback as g } from "react";
3
+ import { useLocalStorage as B } from "./use-local-storage.js";
4
+ import { useInkeepApiClient as P } from "./use-inkeep-api-client.js";
5
+ const p = 30 * 1e3, W = 2147483647, X = () => {
6
+ }, z = async () => ({});
7
+ function $(n) {
8
+ return new Date(n.expiresAt).getTime() - p <= Date.now();
9
9
  }
10
- const X = ({
11
- baseUrl: t,
10
+ const Y = ({
11
+ baseUrl: n,
12
12
  appId: e,
13
- getCaptchaHeader: C,
14
- invalidateCaptcha: d,
15
- optOutAllAnalytics: g
13
+ getCaptchaHeader: D,
14
+ invalidateCaptcha: F,
15
+ optOutAllAnalytics: k,
16
+ enabled: t = !0
16
17
  }) => {
17
- const _ = e && !g ? `inkeep_session_${e}` : null, [i, T] = D(_), { fetchWithAuth: R } = F({
18
+ const L = t && e && !k ? `inkeep_session_${e}` : null, [c, h] = B(L), S = o(t);
19
+ l(() => {
20
+ const r = S.current;
21
+ if (S.current = t, r && !t && e && !k) {
22
+ try {
23
+ localStorage.removeItem(`inkeep_session_${e}`);
24
+ } catch {
25
+ }
26
+ h(null);
27
+ }
28
+ }, [t, e, k, h]);
29
+ const { fetchWithAuth: T } = P({
18
30
  appId: e,
19
31
  authToken: void 0,
20
- getCaptchaHeader: C ?? j,
21
- invalidateCaptcha: d ?? L
22
- }), l = s(t);
23
- l.current = t;
24
- const h = s(e);
25
- h.current = e;
26
- const u = s(i);
27
- u.current = i;
28
- const S = s(T);
29
- S.current = T;
30
- const p = s(R);
31
- p.current = R;
32
- const f = s(null), r = E(async (n) => {
33
- if (!l.current || !h.current) return null;
34
- if (!n && f.current)
35
- return f.current;
36
- const o = `${l.current}/run/auth/apps/${h.current}/anonymous-session`, a = (async () => {
32
+ getCaptchaHeader: D ?? z,
33
+ invalidateCaptcha: F ?? X
34
+ }), y = o(n);
35
+ y.current = n;
36
+ const A = o(e);
37
+ A.current = e;
38
+ const f = o(c);
39
+ f.current = c;
40
+ const w = o(h);
41
+ w.current = h;
42
+ const x = o(T);
43
+ x.current = T;
44
+ const a = o(null), M = o(t);
45
+ M.current = t;
46
+ const s = g(async (r) => {
47
+ if (!M.current || !y.current || !A.current) return null;
48
+ if (!r && a.current)
49
+ return a.current;
50
+ const i = `${y.current}/run/auth/apps/${A.current}/anonymous-session`, m = (async () => {
37
51
  try {
38
- const c = { "Content-Type": "application/json" }, x = u.current?.token;
39
- x && (c.Authorization = `Bearer ${x}`);
40
- const A = await p.current(o, {
52
+ const u = { "Content-Type": "application/json" }, _ = f.current?.token;
53
+ _ && (u.Authorization = `Bearer ${_}`);
54
+ const v = await x.current(i, {
41
55
  method: "POST",
42
- headers: c,
43
- signal: n
56
+ headers: u,
57
+ signal: r
44
58
  });
45
- if (!A.ok) throw new Error(`Failed to fetch anonymous session: ${A.status}`);
46
- const y = await A.json();
47
- return S.current({ token: y.token, expiresAt: y.expiresAt }), y.token;
48
- } catch (c) {
49
- return c instanceof Error && c.name === "AbortError" || console.error("[anonymous-session] fetch failed", c), null;
59
+ if (!v.ok) throw new Error(`Failed to fetch anonymous session: ${v.status}`);
60
+ const E = await v.json();
61
+ return w.current({ token: E.token, expiresAt: E.expiresAt }), E.token;
62
+ } catch (u) {
63
+ return u instanceof Error && u.name === "AbortError" || console.error("[anonymous-session] fetch failed", u), null;
50
64
  } finally {
51
- n || (f.current = null);
65
+ r || (a.current = null);
52
66
  }
53
67
  })();
54
- return n || (f.current = a), a;
55
- }, []), v = s(!1);
56
- k(() => {
57
- if (!t || !e) return;
58
- const n = !v.current;
59
- if (v.current = !0, !n && u.current && !w(u.current) || f.current) return;
60
- const o = new AbortController();
61
- return r(o.signal), () => o.abort();
62
- }, [t, e, r]), k(() => {
63
- if (!t || !e || !i?.expiresAt) return;
64
- const m = new Date(i.expiresAt).getTime() - M - Date.now();
65
- if (m <= 0) return;
66
- const a = setTimeout(() => r(), Math.min(m, b));
67
- return () => clearTimeout(a);
68
- }, [t, e, i?.expiresAt, r]), k(() => {
69
- if (!t || !e) return;
70
- const n = () => {
68
+ return r || (a.current = m), m;
69
+ }, []), C = o(!1);
70
+ l(() => {
71
+ if (!t || !n || !e) return;
72
+ const r = !C.current;
73
+ if (C.current = !0, !r && f.current && !$(f.current) || a.current) return;
74
+ const i = new AbortController();
75
+ return s(i.signal), () => i.abort();
76
+ }, [n, e, t, s]), l(() => {
77
+ if (!t || !n || !e || !c?.expiresAt) return;
78
+ const R = new Date(c.expiresAt).getTime() - p - Date.now();
79
+ if (R <= 0) return;
80
+ const m = setTimeout(() => s(), Math.min(R, W));
81
+ return () => clearTimeout(m);
82
+ }, [n, e, t, c?.expiresAt, s]), l(() => {
83
+ if (!t || !n || !e) return;
84
+ const r = () => {
71
85
  if (document.visibilityState !== "visible") return;
72
- const o = u.current;
73
- (!o || w(o)) && r();
86
+ const i = f.current;
87
+ (!i || $(i)) && s();
74
88
  };
75
- return document.addEventListener("visibilitychange", n), () => document.removeEventListener("visibilitychange", n);
76
- }, [t, e, r]);
77
- const $ = E(() => r(), [r]);
78
- return { sessionToken: i?.token ?? null, refreshSession: $ };
89
+ return document.addEventListener("visibilitychange", r), () => document.removeEventListener("visibilitychange", r);
90
+ }, [n, e, t, s]);
91
+ const j = g(() => s(), [s]);
92
+ return { sessionToken: c?.token ?? null, refreshSession: j };
79
93
  };
80
94
  export {
81
- X as useAnonymousSession
95
+ Y as useAnonymousSession
82
96
  };
@@ -0,0 +1 @@
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react"),T=require("../providers/config-provider.cjs"),p=30*1e3,y=2147483647;function d(c){try{const e=c.split(".")[1];if(!e)return null;const n=JSON.parse(atob(e.replace(/-/g,"+").replace(/_/g,"/")));return typeof n.exp=="number"?n.exp*1e3:null}catch{return null}}const A=()=>{const{baseSettings:c}=T.useInkeepConfig(),{getAuthToken:e}=c,[n,l]=t.useState(null),[h,f]=t.useState(!!e),o=t.useRef(null),i=t.useRef(e);i.current=e;const u=t.useCallback(async()=>{const s=i.current;if(!s)return null;if(o.current)return o.current;const a=(async()=>{try{const r=await s();return l(r),r}catch(r){return console.error("[useAuthToken] getAuthToken failed",r),l(null),null}finally{o.current=null,f(!1)}})();return o.current=a,a},[]);t.useEffect(()=>{if(!e){l(null),f(!1);return}u()},[e,u]),t.useEffect(()=>{if(!e||!n)return;const s=d(n);if(!s)return;const r=s-p-Date.now();if(r<=0)return;const k=setTimeout(()=>u(),Math.min(r,y));return()=>clearTimeout(k)},[e,n,u]);const g=t.useCallback(async()=>i.current?u():null,[u]);return{authToken:n,isLoading:h,refreshToken:g}};exports.useAuthToken=A;
@@ -0,0 +1,5 @@
1
+ export declare const useAuthToken: () => {
2
+ authToken: string | null;
3
+ isLoading: boolean;
4
+ refreshToken: () => Promise<string | null>;
5
+ };
@@ -0,0 +1,54 @@
1
+ "use client";
2
+ import { useState as f, useRef as h, useCallback as p, useEffect as k } from "react";
3
+ import { useInkeepConfig as y } from "../providers/config-provider.js";
4
+ const A = 30 * 1e3, d = 2147483647;
5
+ function M(s) {
6
+ try {
7
+ const e = s.split(".")[1];
8
+ if (!e) return null;
9
+ const t = JSON.parse(atob(e.replace(/-/g, "+").replace(/_/g, "/")));
10
+ return typeof t.exp == "number" ? t.exp * 1e3 : null;
11
+ } catch {
12
+ return null;
13
+ }
14
+ }
15
+ const E = () => {
16
+ const { baseSettings: s } = y(), { getAuthToken: e } = s, [t, c] = f(null), [T, a] = f(!!e), o = h(null), l = h(e);
17
+ l.current = e;
18
+ const r = p(async () => {
19
+ const u = l.current;
20
+ if (!u) return null;
21
+ if (o.current) return o.current;
22
+ const i = (async () => {
23
+ try {
24
+ const n = await u();
25
+ return c(n), n;
26
+ } catch (n) {
27
+ return console.error("[useAuthToken] getAuthToken failed", n), c(null), null;
28
+ } finally {
29
+ o.current = null, a(!1);
30
+ }
31
+ })();
32
+ return o.current = i, i;
33
+ }, []);
34
+ k(() => {
35
+ if (!e) {
36
+ c(null), a(!1);
37
+ return;
38
+ }
39
+ r();
40
+ }, [e, r]), k(() => {
41
+ if (!e || !t) return;
42
+ const u = M(t);
43
+ if (!u) return;
44
+ const n = u - A - Date.now();
45
+ if (n <= 0) return;
46
+ const m = setTimeout(() => r(), Math.min(n, d));
47
+ return () => clearTimeout(m);
48
+ }, [e, t, r]);
49
+ const g = p(async () => l.current ? r() : null, [r]);
50
+ return { authToken: t, isLoading: T, refreshToken: g };
51
+ };
52
+ export {
53
+ E as useAuthToken
54
+ };
@@ -1 +1 @@
1
- "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const E=require("react/jsx-runtime"),t=require("react"),l=require("./config-provider.cjs"),a=t.createContext(void 0),p=({children:e})=>{const{baseSettings:s,componentType:n}=l.useInkeepConfig(),{tags:o,analyticsProperties:r}=s,i=t.useMemo(()=>({widgetLibraryVersion:"0.15.19",componentType:n,tags:o}),[n,o]),u={logEvent:t.useCallback(async c=>{const v={...i,...c.properties,...r},d={eventName:c.eventName,properties:v};return s.onEvent?.(d)},[s,i,r])};return E.jsx(a.Provider,{value:u,children:e})},g=()=>{const e=t.useContext(a);if(!e)throw new Error("useBaseEvents must be used within a BaseEventsProvider");return e};exports.BaseEventsProvider=p;exports.useBaseEvents=g;
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const E=require("react/jsx-runtime"),t=require("react"),l=require("./config-provider.cjs"),a=t.createContext(void 0),p=({children:e})=>{const{baseSettings:s,componentType:n}=l.useInkeepConfig(),{tags:o,analyticsProperties:r}=s,i=t.useMemo(()=>({widgetLibraryVersion:"0.15.21",componentType:n,tags:o}),[n,o]),u={logEvent:t.useCallback(async c=>{const v={...i,...c.properties,...r},d={eventName:c.eventName,properties:v};return s.onEvent?.(d)},[s,i,r])};return E.jsx(a.Provider,{value:u,children:e})},g=()=>{const e=t.useContext(a);if(!e)throw new Error("useBaseEvents must be used within a BaseEventsProvider");return e};exports.BaseEventsProvider=p;exports.useBaseEvents=g;
@@ -5,7 +5,7 @@ import { useInkeepConfig as g } from "./config-provider.js";
5
5
  const a = d(void 0), P = ({ children: e }) => {
6
6
  const { baseSettings: t, componentType: o } = g(), { tags: s, analyticsProperties: n } = t, r = u(
7
7
  () => ({
8
- widgetLibraryVersion: "0.15.19",
8
+ widgetLibraryVersion: "0.15.21",
9
9
  componentType: o,
10
10
  tags: s
11
11
  }),
@@ -1 +1 @@
1
- "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const X=require("react/jsx-runtime"),e=require("react"),Y=require("../components/embedded-chat/chat-provider.cjs"),N=require("./config-provider.cjs"),ee=require("../hooks/use-inkeep-api-client.cjs"),D=e.createContext(void 0),T=25;function te(t){const{stop:a,clear:c,conversationId:u,isStreaming:H,loadAndRestoreSession:P,sessionToken:f,refreshSession:F,getCaptchaHeader:W,invalidateCaptcha:G}=Y.useChat(),{aiChatSettings:K}=N.useInkeepConfig(),{baseUrl:h,appId:k,apiKey:U}=K,o=!U&&!!k,C=f,{fetchWithAuth:I}=ee.useInkeepApiClient({appId:k,authToken:C,getCaptchaHeader:W,invalidateCaptcha:G,refreshSession:F}),[p,S]=e.useState(!1),[R,Z]=e.useState([]),[g,E]=e.useState(!1),[x,_]=e.useState(0),[v,z]=e.useState(!1),b=e.useRef(!1),m=e.useRef(null),q=e.useRef([]);q.current=R;const j=e.useRef(I);j.current=I;const i=e.useCallback(async(s,n=!1)=>{if(!(!h||!C||!o)){n||E(!0);try{const w=`${h}/run/v1/conversations?page=${s+1}&limit=${T}`,y=await j.current(w);if(!y.ok)throw new Error(`Failed to fetch conversations: ${y.status}`);const $=await y.json(),d=($.data??[]).map(r=>({id:r.id,title:r.title??"",createdAt:new Date(r.createdAt),updatedAt:new Date(r.updatedAt)}));Z(r=>{if(s===0&&!n)return d;if(s===0&&n){const l=new Set(d.map(A=>A.id));return[...d,...r.slice(T).filter(A=>!l.has(A.id))]}const V=new Set(r.map(l=>l.id));return[...r,...d.filter(l=>!V.has(l.id))]});const{page:L,pages:O}=$.pagination??{};z(L!=null&&O!=null?L<O:!1),n||_(s)}catch(w){console.error("[useChatHistory] Failed to load conversations:",w)}finally{E(!1)}}},[h,C,o]);e.useEffect(()=>{!p||!f||!o||(t==="stack"?i(0):b.current||(b.current=!0,i(0)))},[p,f,o,t,i]);const M=e.useRef("");e.useEffect(()=>{o&&t==="sidepane"&&(!u||!H||b.current&&M.current!==u&&(q.current.some(s=>s.id===u)||(M.current=u,i(0,!0))))},[u,o,t,i,H]);const B=e.useCallback(()=>{!g&&v&&i(x+1)},[g,v,x,i]),J=e.useCallback(()=>{a(),c(),t!=="sidepane"&&S(!1)},[t,a,c]),Q=e.useCallback(async s=>{m.current?.abort();const n=new AbortController;m.current=n,await P(s,n.signal),!n.signal.aborted&&t!=="sidepane"&&S(!1)},[t,P]);return{isEnabled:o,isOpen:p,setIsOpen:S,sessions:R,isLoading:g,hasMore:v,loadMore:B,startNewConversation:J,loadSession:Q}}const se=({layout:t,children:a})=>{const c=te(t);return X.jsx(D.Provider,{value:c,children:typeof a=="function"?a(c):a})},ne=()=>{const t=e.useContext(D);if(!t)throw new Error("useChatHistory must be used within a ChatHistoryProvider");return t};exports.ChatHistoryProvider=se;exports.useChatHistory=ne;
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const te=require("react/jsx-runtime"),e=require("react"),se=require("../components/embedded-chat/chat-provider.cjs"),ne=require("./config-provider.cjs"),re=require("../hooks/use-inkeep-api-client.cjs"),Z=e.createContext(void 0),U=25;function oe(t){const{stop:u,clear:f,conversationId:l,isStreaming:R,loadAndRestoreSession:H,sessionToken:r,refreshSession:_,getCaptchaHeader:z,invalidateCaptcha:B}=se.useChat(),{aiChatSettings:J,baseSettings:Q}=ne.useInkeepConfig(),{baseUrl:S,appId:I,apiKey:V}=J,i=!!Q.getAuthToken,a=!V&&!!I&&(!!r||i),v=r,{fetchWithAuth:P}=re.useInkeepApiClient({appId:I,authToken:v,getCaptchaHeader:z,invalidateCaptcha:B,refreshSession:_}),[b,k]=e.useState(!1),[E,x]=e.useState([]),[w,m]=e.useState(!1),[T,q]=e.useState(0),[A,j]=e.useState(!1),h=e.useRef(!1),M=e.useRef(null),$=e.useRef(i),L=e.useRef(r);e.useEffect(()=>{const n=$.current,s=L.current;$.current=i,L.current=r,(n!==i||s!==null&&r!==null&&s!==r)&&(x([]),q(0),j(!1),h.current=!1)},[i,r]);const O=e.useRef([]);O.current=E;const D=e.useRef(P);D.current=P;const c=e.useCallback(async(n,s=!1)=>{if(!(!S||!v||!a)){s||m(!0);try{const C=`${S}/run/v1/conversations?page=${n+1}&limit=${U}`,g=await D.current(C);if(!g.ok)throw new Error(`Failed to fetch conversations: ${g.status}`);const W=await g.json(),p=(W.data??[]).map(o=>({id:o.id,title:o.title??"",createdAt:new Date(o.createdAt),updatedAt:new Date(o.updatedAt)}));x(o=>{if(n===0&&!s)return p;if(n===0&&s){const d=new Set(p.map(y=>y.id));return[...p,...o.slice(U).filter(y=>!d.has(y.id))]}const ee=new Set(o.map(d=>d.id));return[...o,...p.filter(d=>!ee.has(d.id))]});const{page:G,pages:K}=W.pagination??{};j(G!=null&&K!=null?G<K:!1),s||q(n)}catch(C){console.error("[useChatHistory] Failed to load conversations:",C)}finally{m(!1)}}},[S,v,a]);e.useEffect(()=>{!b||!r&&!i||!a||(t==="stack"?c(0):h.current||(h.current=!0,c(0)))},[b,r,i,a,t,c]);const F=e.useRef("");e.useEffect(()=>{a&&t==="sidepane"&&(!l||!R||h.current&&F.current!==l&&(O.current.some(n=>n.id===l)||(F.current=l,c(0,!0))))},[l,a,t,c,R]);const X=e.useCallback(()=>{!w&&A&&c(T+1)},[w,A,T,c]),Y=e.useCallback(()=>{u(),f(),t!=="sidepane"&&k(!1)},[t,u,f]),N=e.useCallback(async n=>{M.current?.abort();const s=new AbortController;M.current=s,await H(n,s.signal),!s.signal.aborted&&t!=="sidepane"&&k(!1)},[t,H]);return{isEnabled:a,isOpen:b,setIsOpen:k,sessions:E,isLoading:w,hasMore:A,loadMore:X,startNewConversation:Y,loadSession:N}}const ie=({layout:t,children:u})=>{const f=oe(t);return te.jsx(Z.Provider,{value:f,children:typeof u=="function"?u(f):u})},ae=()=>{const t=e.useContext(Z);if(!t)throw new Error("useChatHistory must be used within a ChatHistoryProvider");return t};exports.ChatHistoryProvider=ie;exports.useChatHistory=ae;
@@ -1,105 +1,110 @@
1
1
  "use client";
2
- import { jsx as tt } from "react/jsx-runtime";
3
- import { createContext as et, useContext as st, useState as f, useRef as d, useCallback as h, useEffect as W } from "react";
4
- import { useChat as nt } from "../components/embedded-chat/chat-provider.js";
5
- import { useInkeepConfig as rt } from "./config-provider.js";
6
- import { useInkeepApiClient as ot } from "../hooks/use-inkeep-api-client.js";
7
- const K = et(void 0), G = 25;
8
- function it(t) {
2
+ import { jsx as re } from "react/jsx-runtime";
3
+ import { createContext as oe, useContext as ie, useState as h, useRef as c, useEffect as y, useCallback as S } from "react";
4
+ import { useChat as ae } from "../components/embedded-chat/chat-provider.js";
5
+ import { useInkeepConfig as ce } from "./config-provider.js";
6
+ import { useInkeepApiClient as ue } from "../hooks/use-inkeep-api-client.js";
7
+ const B = oe(void 0), z = 25;
8
+ function fe(e) {
9
9
  const {
10
- stop: i,
11
- clear: a,
12
- conversationId: c,
13
- isStreaming: y,
14
- loadAndRestoreSession: P,
15
- sessionToken: p,
16
- refreshSession: U,
17
- getCaptchaHeader: Z,
18
- invalidateCaptcha: _
19
- } = nt(), { aiChatSettings: q } = rt(), { baseUrl: C, appId: k, apiKey: z } = q, r = !z && !!k, g = p, { fetchWithAuth: x } = ot({
20
- appId: k,
21
- authToken: g,
22
- getCaptchaHeader: Z,
23
- invalidateCaptcha: _,
24
- refreshSession: U
25
- }), [w, m] = f(!1), [E, B] = f([]), [S, $] = f(!1), [L, J] = f(0), [v, Q] = f(!1), A = d(!1), M = d(null), R = d([]);
26
- R.current = E;
27
- const j = d(x);
28
- j.current = x;
29
- const o = h(
30
- async (e, s = !1) => {
31
- if (!(!C || !g || !r)) {
32
- s || $(!0);
10
+ stop: u,
11
+ clear: f,
12
+ conversationId: d,
13
+ isStreaming: P,
14
+ loadAndRestoreSession: x,
15
+ sessionToken: s,
16
+ refreshSession: J,
17
+ getCaptchaHeader: Q,
18
+ invalidateCaptcha: V
19
+ } = ae(), { aiChatSettings: X, baseSettings: Y } = ce(), { baseUrl: w, appId: E, apiKey: N } = X, o = !!Y.getAuthToken, i = !N && !!E && (!!s || o), m = s, { fetchWithAuth: R } = ue({
20
+ appId: E,
21
+ authToken: m,
22
+ getCaptchaHeader: Q,
23
+ invalidateCaptcha: V,
24
+ refreshSession: J
25
+ }), [A, k] = h(!1), [T, $] = h([]), [b, L] = h(!1), [M, j] = h(0), [I, D] = h(!1), p = c(!1), F = c(null), O = c(o), W = c(s);
26
+ y(() => {
27
+ const n = O.current, t = W.current;
28
+ O.current = o, W.current = s, (n !== o || t !== null && s !== null && t !== s) && ($([]), j(0), D(!1), p.current = !1);
29
+ }, [o, s]);
30
+ const G = c([]);
31
+ G.current = T;
32
+ const K = c(R);
33
+ K.current = R;
34
+ const a = S(
35
+ async (n, t = !1) => {
36
+ if (!(!w || !m || !i)) {
37
+ t || L(!0);
33
38
  try {
34
- const b = `${C}/run/v1/conversations?page=${e + 1}&limit=${G}`, H = await j.current(b);
35
- if (!H.ok) throw new Error(`Failed to fetch conversations: ${H.status}`);
36
- const F = await H.json(), l = (F.data ?? []).map((n) => ({
37
- id: n.id,
38
- title: n.title ?? "",
39
- createdAt: new Date(n.createdAt),
40
- updatedAt: new Date(n.updatedAt)
39
+ const C = `${w}/run/v1/conversations?page=${n + 1}&limit=${z}`, g = await K.current(C);
40
+ if (!g.ok) throw new Error(`Failed to fetch conversations: ${g.status}`);
41
+ const Z = await g.json(), v = (Z.data ?? []).map((r) => ({
42
+ id: r.id,
43
+ title: r.title ?? "",
44
+ createdAt: new Date(r.createdAt),
45
+ updatedAt: new Date(r.updatedAt)
41
46
  }));
42
- B((n) => {
43
- if (e === 0 && !s) return l;
44
- if (e === 0 && s) {
45
- const u = new Set(l.map((I) => I.id));
46
- return [...l, ...n.slice(G).filter((I) => !u.has(I.id))];
47
+ $((r) => {
48
+ if (n === 0 && !t) return v;
49
+ if (n === 0 && t) {
50
+ const l = new Set(v.map((H) => H.id));
51
+ return [...v, ...r.slice(z).filter((H) => !l.has(H.id))];
47
52
  }
48
- const N = new Set(n.map((u) => u.id));
49
- return [...n, ...l.filter((u) => !N.has(u.id))];
53
+ const se = new Set(r.map((l) => l.id));
54
+ return [...r, ...v.filter((l) => !se.has(l.id))];
50
55
  });
51
- const { page: O, pages: T } = F.pagination ?? {};
52
- Q(O != null && T != null ? O < T : !1), s || J(e);
53
- } catch (b) {
54
- console.error("[useChatHistory] Failed to load conversations:", b);
56
+ const { page: _, pages: q } = Z.pagination ?? {};
57
+ D(_ != null && q != null ? _ < q : !1), t || j(n);
58
+ } catch (C) {
59
+ console.error("[useChatHistory] Failed to load conversations:", C);
55
60
  } finally {
56
- $(!1);
61
+ L(!1);
57
62
  }
58
63
  }
59
64
  },
60
- [C, g, r]
65
+ [w, m, i]
61
66
  );
62
- W(() => {
63
- !w || !p || !r || (t === "stack" ? o(0) : A.current || (A.current = !0, o(0)));
64
- }, [w, p, r, t, o]);
65
- const D = d("");
66
- W(() => {
67
- r && t === "sidepane" && (!c || !y || A.current && D.current !== c && (R.current.some((e) => e.id === c) || (D.current = c, o(0, !0))));
68
- }, [c, r, t, o, y]);
69
- const V = h(() => {
70
- !S && v && o(L + 1);
71
- }, [S, v, L, o]), X = h(() => {
72
- i(), a(), t !== "sidepane" && m(!1);
73
- }, [t, i, a]), Y = h(
74
- async (e) => {
75
- M.current?.abort();
76
- const s = new AbortController();
77
- M.current = s, await P(e, s.signal), !s.signal.aborted && t !== "sidepane" && m(!1);
67
+ y(() => {
68
+ !A || !s && !o || !i || (e === "stack" ? a(0) : p.current || (p.current = !0, a(0)));
69
+ }, [A, s, o, i, e, a]);
70
+ const U = c("");
71
+ y(() => {
72
+ i && e === "sidepane" && (!d || !P || p.current && U.current !== d && (G.current.some((n) => n.id === d) || (U.current = d, a(0, !0))));
73
+ }, [d, i, e, a, P]);
74
+ const ee = S(() => {
75
+ !b && I && a(M + 1);
76
+ }, [b, I, M, a]), te = S(() => {
77
+ u(), f(), e !== "sidepane" && k(!1);
78
+ }, [e, u, f]), ne = S(
79
+ async (n) => {
80
+ F.current?.abort();
81
+ const t = new AbortController();
82
+ F.current = t, await x(n, t.signal), !t.signal.aborted && e !== "sidepane" && k(!1);
78
83
  },
79
- [t, P]
84
+ [e, x]
80
85
  );
81
86
  return {
82
- isEnabled: r,
83
- isOpen: w,
84
- setIsOpen: m,
85
- sessions: E,
86
- isLoading: S,
87
- hasMore: v,
88
- loadMore: V,
89
- startNewConversation: X,
90
- loadSession: Y
87
+ isEnabled: i,
88
+ isOpen: A,
89
+ setIsOpen: k,
90
+ sessions: T,
91
+ isLoading: b,
92
+ hasMore: I,
93
+ loadMore: ee,
94
+ startNewConversation: te,
95
+ loadSession: ne
91
96
  };
92
97
  }
93
- const ht = ({ layout: t, children: i }) => {
94
- const a = it(t);
95
- return /* @__PURE__ */ tt(K.Provider, { value: a, children: typeof i == "function" ? i(a) : i });
96
- }, pt = () => {
97
- const t = st(K);
98
- if (!t)
98
+ const ve = ({ layout: e, children: u }) => {
99
+ const f = fe(e);
100
+ return /* @__PURE__ */ re(B.Provider, { value: f, children: typeof u == "function" ? u(f) : u });
101
+ }, Se = () => {
102
+ const e = ie(B);
103
+ if (!e)
99
104
  throw new Error("useChatHistory must be used within a ChatHistoryProvider");
100
- return t;
105
+ return e;
101
106
  };
102
107
  export {
103
- ht as ChatHistoryProvider,
104
- pt as useChatHistory
108
+ ve as ChatHistoryProvider,
109
+ Se as useChatHistory
105
110
  };
@@ -59,8 +59,15 @@ export interface InkeepBaseSettings {
59
59
  /**
60
60
  * Authentication token for the current user.
61
61
  * Used for authenticated API requests if required.
62
+ * @deprecated Use getAuthToken instead for automatic token refresh on 401.
62
63
  */
63
64
  userAuthToken?: string;
65
+ /**
66
+ * Async callback that returns a JWT for authenticated chat sessions.
67
+ * When provided, the widget uses JWT-based auth instead of anonymous sessions.
68
+ * The callback is re-invoked automatically on 401 responses to refresh the token.
69
+ */
70
+ getAuthToken?: () => Promise<string>;
64
71
  /**
65
72
  * Additional properties to be sent with analytics events.
66
73
  * These properties will be merged with the event properties.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inkeep/agents-ui",
3
- "version": "0.15.19",
3
+ "version": "0.15.21",
4
4
  "description": "",
5
5
  "homepage": "",
6
6
  "repository": {