@inkeep/agents-ui 0.16.5 → 0.17.1
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/primitives/components/embedded-chat/chat-error-helpers.cjs +2 -2
- package/dist/primitives/components/embedded-chat/chat-error-helpers.d.ts +3 -2
- package/dist/primitives/components/embedded-chat/chat-error-helpers.js +3 -3
- package/dist/primitives/components/embedded-chat/use-captcha.cjs +1 -1
- package/dist/primitives/components/embedded-chat/use-captcha.d.ts +2 -22
- package/dist/primitives/components/embedded-chat/use-captcha.js +85 -60
- package/dist/primitives/components/embedded-chat.d.ts +1 -1
- package/dist/primitives/hooks/use-anonymous-session.cjs +1 -1
- package/dist/primitives/hooks/use-anonymous-session.js +70 -65
- package/dist/primitives/hooks/use-inkeep-api-client.cjs +1 -1
- package/dist/primitives/hooks/use-inkeep-api-client.d.ts +8 -3
- package/dist/primitives/hooks/use-inkeep-api-client.js +47 -59
- package/dist/primitives/providers/base-events-provider.cjs +1 -1
- package/dist/primitives/providers/base-events-provider.js +1 -1
- package/dist/primitives/providers/chat-auth-provider.cjs +1 -1
- package/dist/primitives/providers/chat-auth-provider.js +29 -32
- package/dist/primitives/providers/chat-base-events-provider.cjs +1 -1
- package/dist/primitives/providers/chat-base-events-provider.js +1 -1
- package/dist/react/embedded-search-and-chat.d.ts +25 -0
- package/dist/react/embedded-search-and-chat.impl.cjs +1 -1
- package/dist/react/embedded-search-and-chat.impl.js +29 -24
- package/package.json +2 -2
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("../../hooks/use-inkeep-api-client.cjs");function
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("../../hooks/use-inkeep-api-client.cjs");function s(t){const e=Number(t.code)||Number(t.statusCode);if(e&&!Number.isNaN(e))return e;try{const r=Number(JSON.parse(t.message??"").status);return r&&!Number.isNaN(r)?r:null}catch{return null}}function o(t){const e=s(t),r=n.parseAuthError(e??0,{detail:t.message??""});return r!==null?r:e===401?"session":e===403?"captcha":null}function a(t){const e=s(t);return e===400||e===429}const u=`Hmm..
|
|
2
2
|
|
|
3
|
-
It seems I might be having some issues right now. Please clear the chat and try again.`,
|
|
3
|
+
It seems I might be having some issues right now. Please clear the chat and try again.`,i="Please try again.",E="You're sending requests too quickly. Please wait a moment and try again.",c=8e3;exports.DEFAULT_ERROR_MESSAGE=u;exports.RATE_LIMIT_MESSAGE=E;exports.RECOVERABLE_FALLBACK_MESSAGE=i;exports.RECOVERABLE_NOTIFICATION_DURATION_MS=c;exports.isRecoverableError=a;exports.resolveHttpStatusCode=s;exports.resolveStreamingAuthError=o;
|
|
@@ -10,9 +10,10 @@ export interface ErrorWithCode extends Error {
|
|
|
10
10
|
*/
|
|
11
11
|
export declare function resolveHttpStatusCode(error: Error): number | null;
|
|
12
12
|
/**
|
|
13
|
-
* Classifies a streaming-transport error as a
|
|
13
|
+
* Classifies a streaming-transport error as a captcha (Sentinel) or session auth failure,
|
|
14
|
+
* or null.
|
|
14
15
|
*/
|
|
15
|
-
export declare function resolveStreamingAuthError(error: Error): '
|
|
16
|
+
export declare function resolveStreamingAuthError(error: Error): 'captcha' | 'session' | null;
|
|
16
17
|
/**
|
|
17
18
|
* Recoverable errors are input-validation failures where the user can fix
|
|
18
19
|
* their input and retry without clearing the conversation.
|
|
@@ -10,9 +10,9 @@ function n(t) {
|
|
|
10
10
|
return null;
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
-
function
|
|
13
|
+
function o(t) {
|
|
14
14
|
const e = n(t), s = r(e ?? 0, { detail: t.message ?? "" });
|
|
15
|
-
return s !== null ? s : e === 401 ? "session" : null;
|
|
15
|
+
return s !== null ? s : e === 401 ? "session" : e === 403 ? "captcha" : null;
|
|
16
16
|
}
|
|
17
17
|
function u(t) {
|
|
18
18
|
const e = n(t);
|
|
@@ -28,5 +28,5 @@ export {
|
|
|
28
28
|
m as RECOVERABLE_NOTIFICATION_DURATION_MS,
|
|
29
29
|
u as isRecoverableError,
|
|
30
30
|
n as resolveHttpStatusCode,
|
|
31
|
-
|
|
31
|
+
o as resolveStreamingAuthError
|
|
32
32
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use client";"use strict";var A=Object.create;var w=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var b=Object.getPrototypeOf,O=Object.prototype.hasOwnProperty;var L=(r,n,e,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of P(n))!O.call(r,t)&&t!==e&&w(r,t,{get:()=>n[t],enumerable:!(o=S(n,t))||o.enumerable});return r};var C=(r,n,e)=>(e=r!=null?A(b(r)):{},L(n||!r||!r.__esModule?w(e,"default",{value:r,enumerable:!0}):e,r));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("react"),h="[sentinel]",x=45e3,M=3e4,N=3,D=5,F=250,I=4e3;let v=null;function Y(){return typeof customElements>"u"||customElements.get("altcha-widget")?Promise.resolve():v||(v=import("altcha").then(()=>customElements.whenDefined("altcha-widget")).then(()=>{}).catch(r=>{throw v=null,console.error(h,"failed to load altcha widget module",r),r instanceof Error?r:new Error("Failed to load altcha widget module")}),v)}function k(r){const n=document.createElement("div");n.style.cssText="position:fixed;left:-9999px;top:-9999px;width:0;height:0;overflow:hidden;pointer-events:none",document.body.appendChild(n);const e=document.createElement("altcha-widget");e.setAttribute("challenge",r),e.setAttribute("auto","onload"),e.setAttribute("hidefooter","true"),e.setAttribute("hidelogo","true"),e.setAttribute("configuration",JSON.stringify({disableAutoFocus:!0})),n.appendChild(e);let o=[],t,c="mounted",s=!1,E=!1,u=null,i=null,a=0,m=!1;const R=d=>{const l=o;o=[];for(const p of l)p(d)},g=()=>{s||m||(t=void 0,c="resetting",e.reset?.(),e.verify?.())},_=()=>{u&&clearTimeout(u),u=setTimeout(()=>{u=null,!(!s||m)&&(s=!1,a=0,t=void 0,c="resetting",e.reset?.(),e.verify?.())},M)},y=d=>{const l=d.detail;if(l&&(c=l.state??c,l.state==="verified"&&l.payload&&(E=!0,a=0,t=l.payload,R(l.payload)),l.state==="error"))if(t=void 0,a++,a>=(E?D:N))R(void 0),s=!0,console.warn(h,`Sentinel unavailable after ${a} consecutive errors, requests will proceed without bot protection`),_();else{const T=Math.min(F*2**(a-1),I);i&&clearTimeout(i),i=setTimeout(()=>{i=null,!(m||s)&&(c="resetting",e.reset?.(),e.verify?.())},T)}};return e.addEventListener("statechange",y),{getPayload:()=>{if(m||s)return Promise.resolve(void 0);if(t){const d=t;return t=void 0,g(),Promise.resolve(d)}return c==="verified"&&g(),new Promise(d=>{o.push(d),setTimeout(()=>{const l=o.indexOf(d);l!==-1&&(o.splice(l,1),d(void 0))},x)})},startNextSolve:g,destroy:()=>{m=!0,e.removeEventListener("statechange",y),u&&(clearTimeout(u),u=null),i&&(clearTimeout(i),i=null),R(void 0),n.remove()}}}const V=({baseUrl:r,appId:n,shouldBypassCaptcha:e=!1})=>{const o=f.useRef(null),t=f.useRef(null),c=f.useRef(!1),s=f.useCallback(()=>o.current?Promise.resolve():t.current?t.current:n?(t.current=Y().then(()=>{if(!c.current&&!o.current){const i=`${r}/run/auth/sentinel/challenge?appId=${encodeURIComponent(n)}`;o.current=k(i)}}).catch(i=>{console.error(h,"failed to mount widget",i),t.current=null}),t.current):Promise.resolve(),[r,n]);f.useEffect(()=>{if(c.current=!1,!e)return s(),()=>{c.current=!0,o.current?.destroy(),o.current=null,t.current=null}},[e,s]);const E=f.useCallback(async()=>{if(e)return{};await s();const i=o.current;if(!i)return{};const a=await i.getPayload();return a?{"x-inkeep-challenge-solution":btoa(JSON.stringify({payload:a}))}:{}},[e,s]),u=f.useCallback(()=>{o.current?.startNextSolve()},[]);return{getCaptchaHeader:E,invalidate:u}};exports.useCaptcha=V;
|
|
@@ -1,29 +1,9 @@
|
|
|
1
|
-
import { Payload } from 'altcha-lib/types';
|
|
2
1
|
interface UseCaptchaOptions {
|
|
3
2
|
baseUrl: string;
|
|
3
|
+
appId: string | undefined;
|
|
4
4
|
shouldBypassCaptcha?: boolean;
|
|
5
|
-
shouldMakeInitialRequest?: boolean;
|
|
6
5
|
}
|
|
7
|
-
|
|
8
|
-
payload: Payload;
|
|
9
|
-
expiresAt: number | null;
|
|
10
|
-
}
|
|
11
|
-
export declare const fetchAndSolveChallenge: (fetchUrl: string) => Promise<SolvedEntry | undefined>;
|
|
12
|
-
/**
|
|
13
|
-
* Manages the PoW captcha lifecycle for /run/* API requests.
|
|
14
|
-
*
|
|
15
|
-
* - getCaptchaHeader(): atomically consumes the current pre-fetched challenge,
|
|
16
|
-
* immediately kicks off the next fetch so a fresh solution is always warm, and
|
|
17
|
-
* returns the ready-to-use `{ 'x-inkeep-challenge-solution': '...' }` header
|
|
18
|
-
* (or {} when bypassing or on failure). Checks token expiry and falls back to
|
|
19
|
-
* the already-started pre-fetch if the resolved token is stale.
|
|
20
|
-
*
|
|
21
|
-
* - invalidate(): discards any in-flight solution and starts a fresh fetch.
|
|
22
|
-
* Call this on request errors to recover from a rejected/stale challenge.
|
|
23
|
-
*
|
|
24
|
-
* All hooks are called unconditionally — bypass logic lives inside callbacks.
|
|
25
|
-
*/
|
|
26
|
-
export declare const useCaptcha: ({ baseUrl, shouldBypassCaptcha, shouldMakeInitialRequest, }: UseCaptchaOptions) => {
|
|
6
|
+
export declare const useCaptcha: ({ baseUrl, appId, shouldBypassCaptcha }: UseCaptchaOptions) => {
|
|
27
7
|
getCaptchaHeader: () => Promise<Record<string, string>>;
|
|
28
8
|
invalidate: () => void;
|
|
29
9
|
};
|
|
@@ -1,67 +1,92 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
function
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
import { useRef as R, useCallback as h, useEffect as A } from "react";
|
|
3
|
+
const y = "[sentinel]", P = 45e3, S = 3e4, O = 3, b = 5, L = 250, x = 4e3;
|
|
4
|
+
let m = null;
|
|
5
|
+
function N() {
|
|
6
|
+
return typeof customElements > "u" || customElements.get("altcha-widget") ? Promise.resolve() : m || (m = import("altcha").then(() => customElements.whenDefined("altcha-widget")).then(() => {
|
|
7
|
+
}).catch((a) => {
|
|
8
|
+
throw m = null, console.error(y, "failed to load altcha widget module", a), a instanceof Error ? a : new Error("Failed to load altcha widget module");
|
|
9
|
+
}), m);
|
|
8
10
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return a ? { "x-inkeep-challenge-solution": btoa(JSON.stringify(a.payload)) } : {};
|
|
11
|
+
function C(a) {
|
|
12
|
+
const d = document.createElement("div");
|
|
13
|
+
d.style.cssText = "position:fixed;left:-9999px;top:-9999px;width:0;height:0;overflow:hidden;pointer-events:none", document.body.appendChild(d);
|
|
14
|
+
const e = document.createElement("altcha-widget");
|
|
15
|
+
e.setAttribute("challenge", a), e.setAttribute("auto", "onload"), e.setAttribute("hidefooter", "true"), e.setAttribute("hidelogo", "true"), e.setAttribute("configuration", JSON.stringify({ disableAutoFocus: !0 })), d.appendChild(e);
|
|
16
|
+
let n = [], t, l = "mounted", i = !1, E = !1, s = null, r = null, c = 0, f = !1;
|
|
17
|
+
const v = (u) => {
|
|
18
|
+
const o = n;
|
|
19
|
+
n = [];
|
|
20
|
+
for (const w of o) w(u);
|
|
21
|
+
}, g = () => {
|
|
22
|
+
i || f || (t = void 0, l = "resetting", e.reset?.(), e.verify?.());
|
|
23
|
+
}, _ = () => {
|
|
24
|
+
s && clearTimeout(s), s = setTimeout(() => {
|
|
25
|
+
s = null, !(!i || f) && (i = !1, c = 0, t = void 0, l = "resetting", e.reset?.(), e.verify?.());
|
|
26
|
+
}, S);
|
|
27
|
+
}, p = (u) => {
|
|
28
|
+
const o = u.detail;
|
|
29
|
+
if (o && (l = o.state ?? l, o.state === "verified" && o.payload && (E = !0, c = 0, t = o.payload, v(o.payload)), o.state === "error"))
|
|
30
|
+
if (t = void 0, c++, c >= (E ? b : O))
|
|
31
|
+
v(void 0), i = !0, console.warn(
|
|
32
|
+
y,
|
|
33
|
+
`Sentinel unavailable after ${c} consecutive errors, requests will proceed without bot protection`
|
|
34
|
+
), _();
|
|
35
|
+
else {
|
|
36
|
+
const T = Math.min(
|
|
37
|
+
L * 2 ** (c - 1),
|
|
38
|
+
x
|
|
39
|
+
);
|
|
40
|
+
r && clearTimeout(r), r = setTimeout(() => {
|
|
41
|
+
r = null, !(f || i) && (l = "resetting", e.reset?.(), e.verify?.());
|
|
42
|
+
}, T);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
return e.addEventListener("statechange", p), { getPayload: () => {
|
|
46
|
+
if (f || i) return Promise.resolve(void 0);
|
|
47
|
+
if (t) {
|
|
48
|
+
const u = t;
|
|
49
|
+
return t = void 0, g(), Promise.resolve(u);
|
|
49
50
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
return l === "verified" && g(), new Promise((u) => {
|
|
52
|
+
n.push(u), setTimeout(() => {
|
|
53
|
+
const o = n.indexOf(u);
|
|
54
|
+
o !== -1 && (n.splice(o, 1), u(void 0));
|
|
55
|
+
}, P);
|
|
56
|
+
});
|
|
57
|
+
}, startNextSolve: g, destroy: () => {
|
|
58
|
+
f = !0, e.removeEventListener("statechange", p), s && (clearTimeout(s), s = null), r && (clearTimeout(r), r = null), v(void 0), d.remove();
|
|
59
|
+
} };
|
|
60
|
+
}
|
|
61
|
+
const M = ({ baseUrl: a, appId: d, shouldBypassCaptcha: e = !1 }) => {
|
|
62
|
+
const n = R(null), t = R(null), l = R(!1), i = h(() => n.current ? Promise.resolve() : t.current ? t.current : d ? (t.current = N().then(() => {
|
|
63
|
+
if (!l.current && !n.current) {
|
|
64
|
+
const r = `${a}/run/auth/sentinel/challenge?appId=${encodeURIComponent(d)}`;
|
|
65
|
+
n.current = C(r);
|
|
53
66
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}, [
|
|
67
|
+
}).catch((r) => {
|
|
68
|
+
console.error(y, "failed to mount widget", r), t.current = null;
|
|
69
|
+
}), t.current) : Promise.resolve(), [a, d]);
|
|
70
|
+
A(() => {
|
|
71
|
+
if (l.current = !1, !e)
|
|
72
|
+
return i(), () => {
|
|
73
|
+
l.current = !0, n.current?.destroy(), n.current = null, t.current = null;
|
|
74
|
+
};
|
|
75
|
+
}, [e, i]);
|
|
76
|
+
const E = h(async () => {
|
|
77
|
+
if (e) return {};
|
|
78
|
+
await i();
|
|
79
|
+
const r = n.current;
|
|
80
|
+
if (!r) return {};
|
|
81
|
+
const c = await r.getPayload();
|
|
82
|
+
return c ? {
|
|
83
|
+
"x-inkeep-challenge-solution": btoa(JSON.stringify({ payload: c }))
|
|
84
|
+
} : {};
|
|
85
|
+
}, [e, i]), s = h(() => {
|
|
86
|
+
n.current?.startNextSolve();
|
|
87
|
+
}, []);
|
|
88
|
+
return { getCaptchaHeader: E, invalidate: s };
|
|
63
89
|
};
|
|
64
90
|
export {
|
|
65
|
-
|
|
66
|
-
k as useCaptcha
|
|
91
|
+
M as useCaptcha
|
|
67
92
|
};
|
|
@@ -294,7 +294,7 @@ export declare const EmbeddedChatPrimitiveFormFieldSelectTrigger: React.ForwardR
|
|
|
294
294
|
declare const PrimitiveFormFieldSelectValue: React.ForwardRefExoticComponent< PolymorphicProps & Omit<SelectPrimitive.SelectValueProps & React.RefAttributes<HTMLSpanElement>, "_id"> & Partial<Pick<SelectPrimitive.SelectValueProps & React.RefAttributes<HTMLSpanElement>, "_id">>>;
|
|
295
295
|
export declare const EmbeddedChatPrimitiveFormFieldSelectValue: (props: ComponentPropsWithRef<typeof PrimitiveFormFieldSelectValue>) => import("react/jsx-runtime").JSX.Element;
|
|
296
296
|
export declare const EmbeddedChatPrimitiveFormFieldSelectIcon: React.ForwardRefExoticComponent< PolymorphicProps & Omit<SelectPrimitive.SelectIconProps & React.RefAttributes<HTMLSpanElement>, "children" | "asChild" | "_id"> & Partial<Pick<SelectPrimitive.SelectIconProps & React.RefAttributes<HTMLSpanElement>, "children" | "asChild" | "_id">>>;
|
|
297
|
-
export declare const EmbeddedChatPrimitiveFormFieldSelectContent: React.ForwardRefExoticComponent< PolymorphicProps & Omit<SelectPrimitive.SelectContentProps & React.RefAttributes<HTMLDivElement>, "
|
|
297
|
+
export declare const EmbeddedChatPrimitiveFormFieldSelectContent: React.ForwardRefExoticComponent< PolymorphicProps & Omit<SelectPrimitive.SelectContentProps & React.RefAttributes<HTMLDivElement>, "_id" | "position"> & Partial<Pick<SelectPrimitive.SelectContentProps & React.RefAttributes<HTMLDivElement>, "_id" | "position">>>;
|
|
298
298
|
export declare const EmbeddedChatPrimitiveFormFieldSelectViewport: React.ForwardRefExoticComponent< PolymorphicProps & Omit<SelectPrimitive.SelectViewportProps & React.RefAttributes<HTMLDivElement>, "_id"> & Partial<Pick<SelectPrimitive.SelectViewportProps & React.RefAttributes<HTMLDivElement>, "_id">>>;
|
|
299
299
|
export declare const EmbeddedChatPrimitiveFormFieldSelectItem: React.ForwardRefExoticComponent< PolymorphicProps & Omit<SelectPrimitive.SelectItemProps & React.RefAttributes<HTMLDivElement>, "_id"> & Partial<Pick<SelectPrimitive.SelectItemProps & React.RefAttributes<HTMLDivElement>, "_id">>>;
|
|
300
300
|
export declare const EmbeddedChatPrimitiveFormFieldSelectItemText: React.ForwardRefExoticComponent< PolymorphicProps & Omit<SelectPrimitive.SelectItemTextProps & React.RefAttributes<HTMLSpanElement>, "_id"> & Partial<Pick<SelectPrimitive.SelectItemTextProps & React.RefAttributes<HTMLSpanElement>, "_id">>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react"),
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react"),P=require("./use-local-storage.cjs"),B=require("./use-inkeep-api-client.cjs"),D=30*1e3,W=2147483647,X=()=>{},v=async()=>({});function j(s){return new Date(s.expiresAt).getTime()-D<=Date.now()}const z=({baseUrl:s,appId:t,getCaptchaHeader:R,invalidateCaptcha:F,optOutAllAnalytics:m,enabled:n=!0})=>{const L=n&&t&&!m?`inkeep_session_${t}`:null,[i,h]=P.useLocalStorage(L),T=e.useRef(n);e.useEffect(()=>{const r=T.current;if(T.current=n,r&&!n&&t&&!m){try{localStorage.removeItem(`inkeep_session_${t}`)}catch{}h(null)}},[n,t,m,h]);const{fetchWithAuth:w}=B.useInkeepApiClient({appId:t,authToken:void 0,getCaptchaHeader:R??v,invalidateCaptcha:F??X}),k=e.useRef(s);k.current=s;const y=e.useRef(t);y.current=t;const f=e.useRef(i);f.current=i;const g=e.useRef(h);g.current=h;const M=e.useRef(w);M.current=w;const x=e.useRef(R??v);x.current=R??v;const a=e.useRef(null),C=e.useRef(n);C.current=n;const o=e.useCallback(async r=>{if(!C.current||!k.current||!y.current)return null;if(!r&&a.current)return a.current;const u=`${k.current}/run/auth/apps/${y.current}/anonymous-session`,l=(async()=>{try{const c={"Content-Type":"application/json"},$=f.current?.token;$&&(c.Authorization=`Bearer ${$}`);const q=await x.current();Object.assign(c,q);const S=await M.current(u,{method:"POST",headers:c,signal:r});if(!S.ok)throw new Error(`Failed to fetch anonymous session: ${S.status}`);const E=await S.json();return g.current({token:E.token,expiresAt:E.expiresAt}),E.token}catch(c){return c instanceof Error&&c.name==="AbortError"||console.error("[anon-session] fetch failed",c),null}finally{r||(a.current=null)}})();return r||(a.current=l),l},[]),_=e.useRef(!1);e.useEffect(()=>{if(!n||!s||!t)return;const r=!_.current;if(_.current=!0,!r&&f.current&&!j(f.current)||a.current)return;const u=new AbortController;return o(u.signal),()=>u.abort()},[s,t,n,o]),e.useEffect(()=>{if(!n||!s||!t||!i?.expiresAt)return;const A=new Date(i.expiresAt).getTime()-D-Date.now();if(A<=0)return;const l=setTimeout(()=>o(),Math.min(A,W));return()=>clearTimeout(l)},[s,t,n,i?.expiresAt,o]),e.useEffect(()=>{if(!n||!s||!t)return;const r=()=>{if(document.visibilityState!=="visible")return;const u=f.current;(!u||j(u))&&o()};return document.addEventListener("visibilitychange",r),()=>document.removeEventListener("visibilitychange",r)},[s,t,n,o]);const p=e.useCallback(()=>o(),[o]);return{sessionToken:i?.token??null,refreshSession:p}};exports.useAnonymousSession=z;
|
|
@@ -1,96 +1,101 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useRef as o, useEffect as l, useCallback as
|
|
3
|
-
import { useLocalStorage as
|
|
4
|
-
import { useInkeepApiClient as
|
|
5
|
-
const
|
|
6
|
-
},
|
|
7
|
-
function
|
|
8
|
-
return new Date(n.expiresAt).getTime() -
|
|
2
|
+
import { useRef as o, useEffect as l, useCallback as D } from "react";
|
|
3
|
+
import { useLocalStorage as X } from "./use-local-storage.js";
|
|
4
|
+
import { useInkeepApiClient as z } from "./use-inkeep-api-client.js";
|
|
5
|
+
const j = 30 * 1e3, H = 2147483647, K = () => {
|
|
6
|
+
}, T = async () => ({});
|
|
7
|
+
function F(n) {
|
|
8
|
+
return new Date(n.expiresAt).getTime() - j <= Date.now();
|
|
9
9
|
}
|
|
10
|
-
const
|
|
10
|
+
const G = ({
|
|
11
11
|
baseUrl: n,
|
|
12
|
-
appId:
|
|
13
|
-
getCaptchaHeader:
|
|
14
|
-
invalidateCaptcha:
|
|
15
|
-
optOutAllAnalytics:
|
|
16
|
-
enabled:
|
|
12
|
+
appId: t,
|
|
13
|
+
getCaptchaHeader: k,
|
|
14
|
+
invalidateCaptcha: L,
|
|
15
|
+
optOutAllAnalytics: y,
|
|
16
|
+
enabled: e = !0
|
|
17
17
|
}) => {
|
|
18
|
-
const
|
|
18
|
+
const B = e && t && !y ? `inkeep_session_${t}` : null, [u, h] = X(B), w = o(e);
|
|
19
19
|
l(() => {
|
|
20
|
-
const r =
|
|
21
|
-
if (
|
|
20
|
+
const r = w.current;
|
|
21
|
+
if (w.current = e, r && !e && t && !y) {
|
|
22
22
|
try {
|
|
23
|
-
localStorage.removeItem(`inkeep_session_${
|
|
23
|
+
localStorage.removeItem(`inkeep_session_${t}`);
|
|
24
24
|
} catch {
|
|
25
25
|
}
|
|
26
26
|
h(null);
|
|
27
27
|
}
|
|
28
|
-
}, [
|
|
29
|
-
const { fetchWithAuth:
|
|
30
|
-
appId:
|
|
28
|
+
}, [e, t, y, h]);
|
|
29
|
+
const { fetchWithAuth: x } = z({
|
|
30
|
+
appId: t,
|
|
31
31
|
authToken: void 0,
|
|
32
|
-
getCaptchaHeader:
|
|
33
|
-
invalidateCaptcha:
|
|
34
|
-
}),
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
const f = o(
|
|
39
|
-
f.current =
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
32
|
+
getCaptchaHeader: k ?? T,
|
|
33
|
+
invalidateCaptcha: L ?? K
|
|
34
|
+
}), A = o(n);
|
|
35
|
+
A.current = n;
|
|
36
|
+
const R = o(t);
|
|
37
|
+
R.current = t;
|
|
38
|
+
const f = o(u);
|
|
39
|
+
f.current = u;
|
|
40
|
+
const M = o(h);
|
|
41
|
+
M.current = h;
|
|
42
|
+
const _ = o(x);
|
|
43
|
+
_.current = x;
|
|
44
|
+
const g = o(k ?? T);
|
|
45
|
+
g.current = k ?? T;
|
|
46
|
+
const a = o(null), C = o(e);
|
|
47
|
+
C.current = e;
|
|
48
|
+
const s = D(async (r) => {
|
|
49
|
+
if (!C.current || !A.current || !R.current) return null;
|
|
48
50
|
if (!r && a.current)
|
|
49
51
|
return a.current;
|
|
50
|
-
const
|
|
52
|
+
const c = `${A.current}/run/auth/apps/${R.current}/anonymous-session`, m = (async () => {
|
|
51
53
|
try {
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
const
|
|
54
|
+
const i = { "Content-Type": "application/json" }, p = f.current?.token;
|
|
55
|
+
p && (i.Authorization = `Bearer ${p}`);
|
|
56
|
+
const W = await g.current();
|
|
57
|
+
Object.assign(i, W);
|
|
58
|
+
const E = await _.current(c, {
|
|
55
59
|
method: "POST",
|
|
56
|
-
headers:
|
|
60
|
+
headers: i,
|
|
57
61
|
signal: r
|
|
58
62
|
});
|
|
59
|
-
if (!
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
if (!E.ok)
|
|
64
|
+
throw new Error(`Failed to fetch anonymous session: ${E.status}`);
|
|
65
|
+
const S = await E.json();
|
|
66
|
+
return M.current({ token: S.token, expiresAt: S.expiresAt }), S.token;
|
|
67
|
+
} catch (i) {
|
|
68
|
+
return i instanceof Error && i.name === "AbortError" || console.error("[anon-session] fetch failed", i), null;
|
|
64
69
|
} finally {
|
|
65
70
|
r || (a.current = null);
|
|
66
71
|
}
|
|
67
72
|
})();
|
|
68
73
|
return r || (a.current = m), m;
|
|
69
|
-
}, []),
|
|
74
|
+
}, []), $ = o(!1);
|
|
70
75
|
l(() => {
|
|
71
|
-
if (!
|
|
72
|
-
const r =
|
|
73
|
-
if (
|
|
74
|
-
const
|
|
75
|
-
return s(
|
|
76
|
-
}, [n,
|
|
77
|
-
if (!
|
|
78
|
-
const
|
|
79
|
-
if (
|
|
80
|
-
const m = setTimeout(() => s(), Math.min(
|
|
76
|
+
if (!e || !n || !t) return;
|
|
77
|
+
const r = !$.current;
|
|
78
|
+
if ($.current = !0, !r && f.current && !F(f.current) || a.current) return;
|
|
79
|
+
const c = new AbortController();
|
|
80
|
+
return s(c.signal), () => c.abort();
|
|
81
|
+
}, [n, t, e, s]), l(() => {
|
|
82
|
+
if (!e || !n || !t || !u?.expiresAt) return;
|
|
83
|
+
const v = new Date(u.expiresAt).getTime() - j - Date.now();
|
|
84
|
+
if (v <= 0) return;
|
|
85
|
+
const m = setTimeout(() => s(), Math.min(v, H));
|
|
81
86
|
return () => clearTimeout(m);
|
|
82
|
-
}, [n,
|
|
83
|
-
if (!
|
|
87
|
+
}, [n, t, e, u?.expiresAt, s]), l(() => {
|
|
88
|
+
if (!e || !n || !t) return;
|
|
84
89
|
const r = () => {
|
|
85
90
|
if (document.visibilityState !== "visible") return;
|
|
86
|
-
const
|
|
87
|
-
(!
|
|
91
|
+
const c = f.current;
|
|
92
|
+
(!c || F(c)) && s();
|
|
88
93
|
};
|
|
89
94
|
return document.addEventListener("visibilitychange", r), () => document.removeEventListener("visibilitychange", r);
|
|
90
|
-
}, [n,
|
|
91
|
-
const
|
|
92
|
-
return { sessionToken:
|
|
95
|
+
}, [n, t, e, s]);
|
|
96
|
+
const P = D(() => s(), [s]);
|
|
97
|
+
return { sessionToken: u?.token ?? null, refreshSession: P };
|
|
93
98
|
};
|
|
94
99
|
export {
|
|
95
|
-
|
|
100
|
+
G as useAnonymousSession
|
|
96
101
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("react");function
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("react");function w(r,e){if(r===400&&typeof e=="object"&&e!==null){const t=(e.detail??"").toLowerCase();if(t.includes("challenge")||t.includes("bot protection")||t.includes("proof-of-work"))return"captcha"}if(r===401&&typeof e=="object"&&e!==null){const t=e.detail??"";if(t.includes("Invalid end-user JWT")||t.includes("Bearer token required"))return"session"}return r===403&&typeof e=="object"&&e!==null&&(e.detail??"").toLowerCase().includes("bot protection")?"captcha":null}function E(r){if(!r)return{};if(r instanceof Headers){const e={};return r.forEach((t,c)=>{e[c]=t}),e}return Array.isArray(r)?Object.fromEntries(r):r}function A(r,e,t,c){return{...r?{"x-inkeep-app-id":r}:{},...e?{Authorization:`Bearer ${e}`}:{},...E(c),...t}}function g({appId:r,authToken:e,getCaptchaHeader:t,invalidateCaptcha:c,refreshSession:i}){const o=u.useRef(r);o.current=r;const f=u.useRef(e);f.current=e;const j=u.useRef(t);j.current=t;const l=u.useRef(c);l.current=c;const a=u.useRef(i);return a.current=i,{fetchWithAuth:u.useCallback(async(d,s)=>{const k=A(o.current,f.current,{},s?.headers),n=await fetch(d,{...s,headers:k});if(n.status!==400&&n.status!==401&&n.status!==403)return n;let h;try{h=await n.clone().json()}catch{return n}const p=w(n.status,h);if(p==="captcha")return l.current(),n;if(p==="session"&&a.current){const R=await a.current();if(!R)return n;const C=A(o.current,R,{},s?.headers);return fetch(d,{...s,headers:C})}return n},[])}}exports.parseAuthError=w;exports.useInkeepApiClient=g;
|
|
@@ -15,10 +15,15 @@ interface UseInkeepApiClientOptions {
|
|
|
15
15
|
* Parses an API error response body to determine the failure type.
|
|
16
16
|
*
|
|
17
17
|
* The Run API returns:
|
|
18
|
-
* - 400 + detail containing "challenge" or "
|
|
19
|
-
* - 401 + detail matching JWT/bearer messages
|
|
18
|
+
* - 400 + detail containing "challenge" or "bot protection" → captcha format failure
|
|
19
|
+
* - 401 + detail matching JWT/bearer messages → session token failure
|
|
20
|
+
* - 403 + detail containing "bot protection verification failed" → captcha rejected
|
|
21
|
+
* (Sentinel classified as bot OR payload was replayed)
|
|
22
|
+
*
|
|
23
|
+
* Legacy "proof-of-work" wording is still matched so older server versions are handled
|
|
24
|
+
* gracefully during the rolling deploy window.
|
|
20
25
|
*/
|
|
21
|
-
export declare function parseAuthError(status: number, body: unknown): '
|
|
26
|
+
export declare function parseAuthError(status: number, body: unknown): 'captcha' | 'session' | null;
|
|
22
27
|
/**
|
|
23
28
|
* Returns a stable `fetchWithAuth` function that automatically:
|
|
24
29
|
* - Injects auth headers (x-inkeep-app-id, Authorization, x-inkeep-challenge-solution)
|
|
@@ -1,87 +1,75 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useRef as
|
|
3
|
-
function E(
|
|
4
|
-
if (
|
|
5
|
-
const t = (
|
|
6
|
-
if (t.includes("challenge") || t.includes("proof-of-work"))
|
|
2
|
+
import { useRef as s, useCallback as C } from "react";
|
|
3
|
+
function E(r, e) {
|
|
4
|
+
if (r === 400 && typeof e == "object" && e !== null) {
|
|
5
|
+
const t = (e.detail ?? "").toLowerCase();
|
|
6
|
+
if (t.includes("challenge") || t.includes("bot protection") || t.includes("proof-of-work"))
|
|
7
|
+
return "captcha";
|
|
7
8
|
}
|
|
8
|
-
if (
|
|
9
|
-
const t =
|
|
9
|
+
if (r === 401 && typeof e == "object" && e !== null) {
|
|
10
|
+
const t = e.detail ?? "";
|
|
10
11
|
if (t.includes("Invalid end-user JWT") || t.includes("Bearer token required"))
|
|
11
12
|
return "session";
|
|
12
13
|
}
|
|
13
|
-
return null;
|
|
14
|
+
return r === 403 && typeof e == "object" && e !== null && (e.detail ?? "").toLowerCase().includes("bot protection") ? "captcha" : null;
|
|
14
15
|
}
|
|
15
|
-
function m(
|
|
16
|
-
if (!
|
|
17
|
-
if (
|
|
18
|
-
const
|
|
19
|
-
return
|
|
20
|
-
|
|
21
|
-
}),
|
|
16
|
+
function m(r) {
|
|
17
|
+
if (!r) return {};
|
|
18
|
+
if (r instanceof Headers) {
|
|
19
|
+
const e = {};
|
|
20
|
+
return r.forEach((t, c) => {
|
|
21
|
+
e[c] = t;
|
|
22
|
+
}), e;
|
|
22
23
|
}
|
|
23
|
-
return Array.isArray(
|
|
24
|
+
return Array.isArray(r) ? Object.fromEntries(r) : r;
|
|
24
25
|
}
|
|
25
|
-
function
|
|
26
|
+
function A(r, e, t, c) {
|
|
26
27
|
return {
|
|
27
|
-
...
|
|
28
|
-
...
|
|
28
|
+
...r ? { "x-inkeep-app-id": r } : {},
|
|
29
|
+
...e ? { Authorization: `Bearer ${e}` } : {},
|
|
29
30
|
...m(c),
|
|
30
31
|
// captcha last — must not be overridden by caller headers
|
|
31
32
|
...t
|
|
32
33
|
};
|
|
33
34
|
}
|
|
34
|
-
function
|
|
35
|
-
appId:
|
|
36
|
-
authToken:
|
|
35
|
+
function W({
|
|
36
|
+
appId: r,
|
|
37
|
+
authToken: e,
|
|
37
38
|
getCaptchaHeader: t,
|
|
38
39
|
invalidateCaptcha: c,
|
|
39
|
-
refreshSession:
|
|
40
|
+
refreshSession: i
|
|
40
41
|
}) {
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
return
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
C,
|
|
55
|
-
s?.headers
|
|
56
|
-
), n = await fetch(d, { ...s, headers: H });
|
|
57
|
-
if (n.status !== 400 && n.status !== 401) return n;
|
|
58
|
-
let R;
|
|
42
|
+
const o = s(r);
|
|
43
|
+
o.current = r;
|
|
44
|
+
const f = s(e);
|
|
45
|
+
f.current = e;
|
|
46
|
+
const R = s(t);
|
|
47
|
+
R.current = t;
|
|
48
|
+
const l = s(c);
|
|
49
|
+
l.current = c;
|
|
50
|
+
const a = s(i);
|
|
51
|
+
return a.current = i, { fetchWithAuth: C(async (h, u) => {
|
|
52
|
+
const j = A(o.current, f.current, {}, u?.headers), n = await fetch(h, { ...u, headers: j });
|
|
53
|
+
if (n.status !== 400 && n.status !== 401 && n.status !== 403) return n;
|
|
54
|
+
let d;
|
|
59
55
|
try {
|
|
60
|
-
|
|
56
|
+
d = await n.clone().json();
|
|
61
57
|
} catch {
|
|
62
58
|
return n;
|
|
63
59
|
}
|
|
64
|
-
const
|
|
65
|
-
if (
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
);
|
|
73
|
-
return fetch(d, { ...s, headers: l });
|
|
74
|
-
}
|
|
75
|
-
if (k === "session" && h.current) {
|
|
76
|
-
const f = await h.current();
|
|
77
|
-
if (!f) return n;
|
|
78
|
-
const l = await o.current(), j = p(a.current, f, l, s?.headers);
|
|
79
|
-
return fetch(d, { ...s, headers: j });
|
|
60
|
+
const p = E(n.status, d);
|
|
61
|
+
if (p === "captcha")
|
|
62
|
+
return l.current(), n;
|
|
63
|
+
if (p === "session" && a.current) {
|
|
64
|
+
const w = await a.current();
|
|
65
|
+
if (!w) return n;
|
|
66
|
+
const k = A(o.current, w, {}, u?.headers);
|
|
67
|
+
return fetch(h, { ...u, headers: k });
|
|
80
68
|
}
|
|
81
69
|
return n;
|
|
82
70
|
}, []) };
|
|
83
71
|
}
|
|
84
72
|
export {
|
|
85
73
|
E as parseAuthError,
|
|
86
|
-
|
|
74
|
+
W as useInkeepApiClient
|
|
87
75
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("react/jsx-runtime"),t=require("react"),p=require("./config-provider.cjs"),n=t.createContext(void 0),g=({children:e})=>{const{baseSettings:s,componentType:o}=p.useInkeepConfig(),{tags:r,analyticsProperties:i}=s,c="0.
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("react/jsx-runtime"),t=require("react"),p=require("./config-provider.cjs"),n=t.createContext(void 0),g=({children:e})=>{const{baseSettings:s,componentType:o}=p.useInkeepConfig(),{tags:r,analyticsProperties:i}=s,c="0.17.1",a=t.useMemo(()=>({widgetLibraryVersion:c,componentType:o,tags:r}),[o,r,c]),v={logEvent:t.useCallback(async u=>{const E={...a,...u.properties,...i},d={eventName:u.eventName,properties:E};return s.onEvent?.(d)},[s,a,i])};return l.jsx(n.Provider,{value:v,children:e})},m=()=>{const e=t.useContext(n);if(!e)throw new Error("useBaseEvents must be used within a BaseEventsProvider");return e};exports.BaseEventsContext=n;exports.BaseEventsProvider=g;exports.useBaseEvents=m;
|
|
@@ -3,7 +3,7 @@ import { jsx as u } from "react/jsx-runtime";
|
|
|
3
3
|
import { createContext as E, useMemo as d, useCallback as l, useContext as g } from "react";
|
|
4
4
|
import { useInkeepConfig as x } from "./config-provider.js";
|
|
5
5
|
const c = E(void 0), b = ({ children: e }) => {
|
|
6
|
-
const { baseSettings: t, componentType: o } = x(), { tags: s, analyticsProperties: n } = t, r = "0.
|
|
6
|
+
const { baseSettings: t, componentType: o } = x(), { tags: s, analyticsProperties: n } = t, r = "0.17.1", i = d(
|
|
7
7
|
() => ({
|
|
8
8
|
widgetLibraryVersion: r,
|
|
9
9
|
componentType: o,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=require("react/jsx-runtime"),d=require("react"),T=require("./config-provider.cjs"),S=require("../hooks/use-auth-token.cjs"),b=require("../components/embedded-chat/use-captcha.cjs"),P=require("../hooks/use-anonymous-session.cjs"),l=d.createContext(void 0),q=({children:e})=>{const{baseSettings:o,aiChatSettings:p}=T.useInkeepConfig(),{shouldBypassCaptcha:C,privacyPreferences:f}=o,{baseUrl:i,appId:u,apiKey:s}=p,{authToken:n,isLoading:a,refreshToken:v}=S.useAuthToken(),g=!!o.getAuthToken,t=!!n,{getCaptchaHeader:r,invalidate:c}=b.useCaptcha({baseUrl:i,appId:u,shouldBypassCaptcha:C||!!s}),{sessionToken:h,refreshSession:A}=P.useAnonymousSession({baseUrl:i,appId:u,getCaptchaHeader:r,invalidateCaptcha:c,optOutAllAnalytics:f?.optOutAllAnalytics,enabled:!t&&!a}),k={authToken:n,isAuthenticated:t,isAuthLoading:a,isAuthConfigured:g,refreshAuthToken:v,sessionToken:h,refreshSession:A,getCaptchaHeader:r,invalidateCaptcha:c,effectiveAuthToken:s??(t?n:h),applicableRefreshSession:s||t?void 0:A};return y.jsx(l.Provider,{value:k,children:e})},x=()=>{const e=d.useContext(l);if(!e)throw new Error("useChatAuth must be used within a ChatAuthProvider");return e};exports.ChatAuthProvider=q;exports.useChatAuth=x;
|
|
@@ -1,46 +1,43 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as
|
|
3
|
-
import { useContext as
|
|
4
|
-
import { useInkeepConfig as
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
import { useAnonymousSession as L } from "../hooks/use-anonymous-session.js";
|
|
11
|
-
const p = S(void 0), J = ({ children: t }) => {
|
|
12
|
-
const { baseSettings: n, aiChatSettings: l } = x(), { shouldBypassCaptcha: d, privacyPreferences: f } = n, { baseUrl: i, appId: m, apiKey: o } = l, C = w(), A = B(), b = I(), v = C?.isOpen ?? A?.isOpen ?? b?.isOpen ?? !0, { authToken: s, isLoading: a, refreshToken: k } = P(), g = !!n.getAuthToken, e = !!s, { getCaptchaHeader: r, invalidate: u } = R({
|
|
2
|
+
import { jsx as k } from "react/jsx-runtime";
|
|
3
|
+
import { useContext as g, createContext as T } from "react";
|
|
4
|
+
import { useInkeepConfig as y } from "./config-provider.js";
|
|
5
|
+
import { useAuthToken as b } from "../hooks/use-auth-token.js";
|
|
6
|
+
import { useCaptcha as x } from "../components/embedded-chat/use-captcha.js";
|
|
7
|
+
import { useAnonymousSession as S } from "../hooks/use-anonymous-session.js";
|
|
8
|
+
const f = T(void 0), E = ({ children: t }) => {
|
|
9
|
+
const { baseSettings: n, aiChatSettings: l } = y(), { shouldBypassCaptcha: A, privacyPreferences: d } = n, { baseUrl: i, appId: a, apiKey: o } = l, { authToken: s, isLoading: r, refreshToken: C } = b(), m = !!n.getAuthToken, e = !!s, { getCaptchaHeader: h, invalidate: u } = x({
|
|
13
10
|
baseUrl: i,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}), { sessionToken:
|
|
11
|
+
appId: a,
|
|
12
|
+
shouldBypassCaptcha: A || !!o
|
|
13
|
+
}), { sessionToken: c, refreshSession: p } = S({
|
|
17
14
|
baseUrl: i,
|
|
18
|
-
appId:
|
|
19
|
-
getCaptchaHeader:
|
|
15
|
+
appId: a,
|
|
16
|
+
getCaptchaHeader: h,
|
|
20
17
|
invalidateCaptcha: u,
|
|
21
|
-
optOutAllAnalytics:
|
|
22
|
-
enabled: !e && !
|
|
23
|
-
}),
|
|
18
|
+
optOutAllAnalytics: d?.optOutAllAnalytics,
|
|
19
|
+
enabled: !e && !r
|
|
20
|
+
}), v = {
|
|
24
21
|
authToken: s,
|
|
25
22
|
isAuthenticated: e,
|
|
26
|
-
isAuthLoading:
|
|
27
|
-
isAuthConfigured:
|
|
28
|
-
refreshAuthToken:
|
|
29
|
-
sessionToken:
|
|
30
|
-
refreshSession:
|
|
31
|
-
getCaptchaHeader:
|
|
23
|
+
isAuthLoading: r,
|
|
24
|
+
isAuthConfigured: m,
|
|
25
|
+
refreshAuthToken: C,
|
|
26
|
+
sessionToken: c,
|
|
27
|
+
refreshSession: p,
|
|
28
|
+
getCaptchaHeader: h,
|
|
32
29
|
invalidateCaptcha: u,
|
|
33
|
-
effectiveAuthToken: o ?? (e ? s :
|
|
34
|
-
applicableRefreshSession: o || e ? void 0 :
|
|
30
|
+
effectiveAuthToken: o ?? (e ? s : c),
|
|
31
|
+
applicableRefreshSession: o || e ? void 0 : p
|
|
35
32
|
};
|
|
36
|
-
return /* @__PURE__ */
|
|
37
|
-
},
|
|
38
|
-
const t =
|
|
33
|
+
return /* @__PURE__ */ k(f.Provider, { value: v, children: t });
|
|
34
|
+
}, H = () => {
|
|
35
|
+
const t = g(f);
|
|
39
36
|
if (!t)
|
|
40
37
|
throw new Error("useChatAuth must be used within a ChatAuthProvider");
|
|
41
38
|
return t;
|
|
42
39
|
};
|
|
43
40
|
export {
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
E as ChatAuthProvider,
|
|
42
|
+
H as useChatAuth
|
|
46
43
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const j=require("react/jsx-runtime"),u=require("react"),B=require("./config-provider.cjs"),O=require("./chat-auth-provider.cjs"),U=require("../hooks/use-events-api.cjs"),x=require("./base-events-provider.cjs"),M=({children:g})=>{const{baseSettings:n,aiChatSettings:h,componentType:i}=B.useInkeepConfig(),{tags:t,analyticsProperties:r,privacyPreferences:y,userProperties:o}=n,c="0.
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const j=require("react/jsx-runtime"),u=require("react"),B=require("./config-provider.cjs"),O=require("./chat-auth-provider.cjs"),U=require("../hooks/use-events-api.cjs"),x=require("./base-events-provider.cjs"),M=({children:g})=>{const{baseSettings:n,aiChatSettings:h,componentType:i}=B.useInkeepConfig(),{tags:t,analyticsProperties:r,privacyPreferences:y,userProperties:o}=n,c="0.17.1",a=u.useMemo(()=>({widgetLibraryVersion:c,componentType:i}),[i,c]),{effectiveAuthToken:b,applicableRefreshSession:f,getCaptchaHeader:E,invalidateCaptcha:P}=O.useChatAuth(),{baseUrl:m,appId:A,analyticsApiBaseUrl:C,headers:I}=h,p=y?.optOutAllAnalytics??!1,{logEvent:l}=U.useEventsApi({baseUrl:C??m,appId:A,authToken:b,getCaptchaHeader:E,invalidateCaptcha:P,refreshSession:f,headers:I}),k={logEvent:u.useCallback(async s=>{const q={eventName:s.eventName,properties:{...a,...t?{tags:t}:{},...s.properties,...r}};if(!p){const e=s.properties??{},v=typeof e.conversationId=="string"?e.conversationId:void 0,d=typeof e.messageId=="string"?e.messageId:void 0,S=!!o&&Object.keys(o).length>0,w={...t?{tags:t}:{},...r??{}},T={...a,...s.properties};l({body:{type:s.eventName,...v?{conversationId:v}:{},...d?{messageId:d}:{},...S?{userProperties:o}:{},properties:w,metadata:T}})}try{return await n.onEvent?.(q)}catch(e){console.warn("[events] onEvent callback threw",e)}},[n,a,t,r,l,p,o])};return j.jsx(x.BaseEventsContext.Provider,{value:k,children:g})};exports.ChatBaseEventsProvider=M;
|
|
@@ -6,7 +6,7 @@ import { useChatAuth as O } from "./chat-auth-provider.js";
|
|
|
6
6
|
import { useEventsApi as j } from "../hooks/use-events-api.js";
|
|
7
7
|
import { BaseEventsContext as M } from "./base-events-provider.js";
|
|
8
8
|
const F = ({ children: m }) => {
|
|
9
|
-
const { baseSettings: r, aiChatSettings: g, componentType: i } = N(), { tags: t, analyticsProperties: n, privacyPreferences: f, userProperties: o } = r, c = "0.
|
|
9
|
+
const { baseSettings: r, aiChatSettings: g, componentType: i } = N(), { tags: t, analyticsProperties: n, privacyPreferences: f, userProperties: o } = r, c = "0.17.1", a = x(
|
|
10
10
|
() => ({
|
|
11
11
|
widgetLibraryVersion: c,
|
|
12
12
|
componentType: i
|
|
@@ -5,6 +5,31 @@ export interface InkeepEmbeddedSearchAndChatFunctions {
|
|
|
5
5
|
setView: (view: ModalViewTypes) => void;
|
|
6
6
|
}
|
|
7
7
|
export interface InkeepEmbeddedSearchAndChatProps extends Partial<Omit<InkeepConfig, 'componentType'>>, WidgetView {
|
|
8
|
+
/**
|
|
9
|
+
* Callback fired when the user selects "Ask AI" — via the Ask AI card or the
|
|
10
|
+
* Search/Ask AI toggle.
|
|
11
|
+
*
|
|
12
|
+
* When provided, this replaces the default behavior of switching to the
|
|
13
|
+
* component's internal chat view. The internal chat pane is not shown and no
|
|
14
|
+
* message is submitted to it; instead the parent handles the Ask AI intent
|
|
15
|
+
* (for example, closing the modal and opening a separate sidebar chat).
|
|
16
|
+
*
|
|
17
|
+
* `query` is the current search input, so the parent can autofill or submit it
|
|
18
|
+
* in the destination chat.
|
|
19
|
+
*
|
|
20
|
+
* `autoSubmit` reflects the user's intent based on how they selected Ask AI:
|
|
21
|
+
* `true` when they clicked the Ask AI card (a query-specific action), and
|
|
22
|
+
* `false`/`undefined` when they used the Search/Ask AI toggle (a mode switch).
|
|
23
|
+
* Honor it to decide between auto-submitting and only filling in the query.
|
|
24
|
+
*
|
|
25
|
+
* Precedence: this takes full ownership of the Ask AI intent. When it is
|
|
26
|
+
* provided, `onToggleView` is NOT called for `view: 'chat'` selections and the
|
|
27
|
+
* internal view does not change. `onToggleView` still fires for `view: 'search'`.
|
|
28
|
+
*/
|
|
29
|
+
onSelectAskAI?: (opts: {
|
|
30
|
+
query?: string;
|
|
31
|
+
autoSubmit?: boolean;
|
|
32
|
+
}) => void;
|
|
8
33
|
/**
|
|
9
34
|
* The default view to show when the widget is loaded.
|
|
10
35
|
* @default 'search'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react"),
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react"),f=require("./utils.cjs");function y(g){const{defaultView:c="search",aiChatSettings:i,baseSettings:l,searchSettings:o,shouldAutoFocusInput:h=!0,onToggleView:S,onSelectAskAI:r,ref:R,...m}=g,s=t.useRef(null),w=f.composeRefs(s,i?.chatFunctionsRef),a=t.useRef(null),b=f.composeRefs(a,o?.searchFunctionsRef),d={...i,chatFunctionsRef:w},I={...o,searchFunctionsRef:b},[n,u]=t.useState(c),q=e=>{if(e.view==="chat"&&r){r({query:e.query,autoSubmit:e.autoSubmit});return}e.autoSubmit&&e.query&&s.current?.submitMessage(e.query),S?.(e),u(e.view)};return t.useImperativeHandle(R,()=>({setView:u})),t.useEffect(()=>{n==="chat"?s.current?.focusInput():a.current?.focusInput()},[n]),{config:{baseSettings:l,aiChatSettings:d,searchSettings:I},defaultView:c,view:n,setView:u,onToggleView:q,shouldAutoFocusInput:h,...m}}exports.useWidgetImpl=y;
|
|
@@ -1,43 +1,48 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useRef as
|
|
3
|
-
import { composeRefs as
|
|
4
|
-
function
|
|
2
|
+
import { useRef as a, useState as d, useImperativeHandle as q, useEffect as v } from "react";
|
|
3
|
+
import { composeRefs as f } from "./utils.js";
|
|
4
|
+
function T(g) {
|
|
5
5
|
const {
|
|
6
6
|
defaultView: c = "search",
|
|
7
|
-
aiChatSettings:
|
|
8
|
-
baseSettings:
|
|
9
|
-
searchSettings:
|
|
10
|
-
shouldAutoFocusInput:
|
|
11
|
-
onToggleView:
|
|
7
|
+
aiChatSettings: u,
|
|
8
|
+
baseSettings: h,
|
|
9
|
+
searchSettings: i,
|
|
10
|
+
shouldAutoFocusInput: l = !0,
|
|
11
|
+
onToggleView: S,
|
|
12
|
+
onSelectAskAI: o,
|
|
12
13
|
ref: m,
|
|
13
|
-
...
|
|
14
|
-
} =
|
|
15
|
-
...
|
|
14
|
+
...w
|
|
15
|
+
} = g, t = a(null), R = f(t, u?.chatFunctionsRef), r = a(null), I = f(r, i?.searchFunctionsRef), b = {
|
|
16
|
+
...u,
|
|
16
17
|
chatFunctionsRef: R
|
|
17
18
|
}, F = {
|
|
18
|
-
...
|
|
19
|
-
searchFunctionsRef:
|
|
20
|
-
}, [n, s] =
|
|
21
|
-
e.
|
|
19
|
+
...i,
|
|
20
|
+
searchFunctionsRef: I
|
|
21
|
+
}, [n, s] = d(c), V = (e) => {
|
|
22
|
+
if (e.view === "chat" && o) {
|
|
23
|
+
o({ query: e.query, autoSubmit: e.autoSubmit });
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
e.autoSubmit && e.query && t.current?.submitMessage(e.query), S?.(e), s(e.view);
|
|
22
27
|
};
|
|
23
|
-
return
|
|
28
|
+
return q(m, () => ({
|
|
24
29
|
setView: s
|
|
25
|
-
})),
|
|
26
|
-
n === "chat" ? t.current?.focusInput() :
|
|
30
|
+
})), v(() => {
|
|
31
|
+
n === "chat" ? t.current?.focusInput() : r.current?.focusInput();
|
|
27
32
|
}, [n]), {
|
|
28
33
|
config: {
|
|
29
|
-
baseSettings:
|
|
30
|
-
aiChatSettings:
|
|
34
|
+
baseSettings: h,
|
|
35
|
+
aiChatSettings: b,
|
|
31
36
|
searchSettings: F
|
|
32
37
|
},
|
|
33
38
|
defaultView: c,
|
|
34
39
|
view: n,
|
|
35
40
|
setView: s,
|
|
36
|
-
onToggleView:
|
|
37
|
-
shouldAutoFocusInput:
|
|
38
|
-
...
|
|
41
|
+
onToggleView: V,
|
|
42
|
+
shouldAutoFocusInput: l,
|
|
43
|
+
...w
|
|
39
44
|
};
|
|
40
45
|
}
|
|
41
46
|
export {
|
|
42
|
-
|
|
47
|
+
T as useWidgetImpl
|
|
43
48
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inkeep/agents-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"homepage": "",
|
|
6
6
|
"repository": {
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"@zag-js/react": "^1.38.1",
|
|
73
73
|
"@zag-js/remove-scroll": "^1.38.1",
|
|
74
74
|
"ai": "6.0.44",
|
|
75
|
-
"altcha
|
|
75
|
+
"altcha": "^3.0.9",
|
|
76
76
|
"aria-hidden": "^1.2.4",
|
|
77
77
|
"class-variance-authority": "0.7.1",
|
|
78
78
|
"clsx": "2.1.1",
|