@inkeep/agents-ui 0.17.6 → 0.17.8

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 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),f=require("react"),w=require("react-markdown"),M=require("rehype-raw"),y=require("remark-gfm"),g=require("remark-supersub"),b=require("../../providers/markdown-provider.cjs"),S=require("../codeblock/index.cjs"),t=require("./components.cjs"),q=require("./rehype-inline-code-property.cjs");const C=({children:c,componentStyles:h,shouldOpenLinksInNewTab:d,onLinkClick:l,onCodeCopy:m,artifacts:x,...j})=>{if(!c)return null;const k={h1:({children:r})=>e.jsx(t.MarkdownH1,{children:r}),h2:({children:r})=>e.jsx(t.MarkdownH2,{children:r}),p:({children:r})=>e.jsx(t.MarkdownP,{children:r}),li:({children:r})=>e.jsx(t.MarkdownLi,{children:r}),ul:({children:r})=>e.jsx(t.MarkdownUl,{children:r}),hr:()=>e.jsx(t.MarkdownHr,{}),input:({type:r,checked:o,disabled:n,readOnly:s,required:a,value:i})=>e.jsx(t.MarkdownInput,{type:r,checked:o,disabled:n,readOnly:s,required:a,value:i}),ol:({children:r,node:o})=>{const n=o?.properties?.start,s=typeof n=="number"?n:void 0;return e.jsx(t.MarkdownOl,{style:{"--start":n?.toString()??"0"},start:s,children:r})},a:({children:r,href:o})=>{const n=f.Children.toArray(r),s=n[0],a=typeof s=="string"&&/^\(\d+\)$/.test(s)&&n.length===1,i=a?s.match(/\d+/):r,u=e.jsx(t.MarkdownLink,{isExternal:d,href:o,onClick:()=>{l?.(o,i?.toString())},children:i});return a?e.jsx(t.MarkdownSourceLink,{children:u}):u},img:({src:r,alt:o})=>e.jsx(t.MarkdownImg,{src:r,alt:o}),table:({children:r})=>e.jsx(t.MarkdownTable,{children:r}),th:({children:r,isHeader:o})=>o?e.jsx(t.MarkdownTh,{children:r}):e.jsx(t.MarkdownTd,{children:r}),pre:({children:r})=>e.jsx("pre",{children:r}),code:({children:r,inline:o,className:n})=>o?e.jsx(t.MarkdownCode,{children:r}):e.jsx(S.CodeBlock,{className:n,onCopy:m,children:r}),sub:({children:r})=>typeof r=="string"&&(r.startsWith(" ")||r.endsWith(" "))?e.jsxs(e.Fragment,{children:["~",r,"~"]}):e.jsx("sub",{children:r}),sup:({children:r})=>{if(r&&typeof r=="string"){const o=x?.find(n=>(n.data?.artifactSummary?.title||n.data?.name)===r);if(o){const n=o.data,s=n?.artifactSummary?.url,a=n?.artifactSummary?.title;if(!s)return null;const i=a||n?.name||r;return e.jsx(t.MarkdownSup,{children:e.jsx(t.MarkdownLink,{href:s,isExternal:d,onClick:()=>l?.(s,i),children:e.jsx("span",{children:i})})})}}return e.jsx("sup",{children:r})}},p=e.jsx(w,{remarkPlugins:[[y,{singleTilde:!1}],g],rehypePlugins:[M,q.rehypeInlineCodeProperty],components:k,disallowedElements:P,children:c.toString(),...j});return e.jsx(b.ChatMarkdownProvider,{componentStyles:h,children:p})},P=["script","iframe","frame","embed","meta","base","form","style","object"];exports.Markdown=C;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),l=require("react"),f=require("react-markdown"),y=require("rehype-raw"),g=require("remark-gfm"),b=require("remark-supersub"),S=require("../../providers/markdown-provider.cjs"),q=require("../codeblock/index.cjs"),t=require("./components.cjs"),P=require("./rehype-inline-code-property.cjs");const C=[[g,{singleTilde:!1}],b],v=[y,P.rehypeInlineCodeProperty],j=l.memo(function({children:u,componentStyles:k,shouldOpenLinksInNewTab:c,onLinkClick:d,onCodeCopy:h,artifacts:m,...p}){const M=l.useMemo(()=>({h1:({children:r})=>e.jsx(t.MarkdownH1,{children:r}),h2:({children:r})=>e.jsx(t.MarkdownH2,{children:r}),p:({children:r})=>e.jsx(t.MarkdownP,{children:r}),li:({children:r})=>e.jsx(t.MarkdownLi,{children:r}),ul:({children:r})=>e.jsx(t.MarkdownUl,{children:r}),hr:()=>e.jsx(t.MarkdownHr,{}),input:({type:r,checked:o,disabled:n,readOnly:s,required:a,value:i})=>e.jsx(t.MarkdownInput,{type:r,checked:o,disabled:n,readOnly:s,required:a,value:i}),ol:({children:r,node:o})=>{const n=o?.properties?.start,s=typeof n=="number"?n:void 0;return e.jsx(t.MarkdownOl,{style:{"--start":n?.toString()??"0"},start:s,children:r})},a:({children:r,href:o})=>{const n=l.Children.toArray(r),s=n[0],a=typeof s=="string"&&/^\(\d+\)$/.test(s)&&n.length===1,i=a?s.match(/\d+/):r,x=e.jsx(t.MarkdownLink,{isExternal:c,href:o,onClick:()=>{d?.(o,i?.toString())},children:i});return a?e.jsx(t.MarkdownSourceLink,{children:x}):x},img:({src:r,alt:o})=>e.jsx(t.MarkdownImg,{src:r,alt:o}),table:({children:r})=>e.jsx(t.MarkdownTable,{children:r}),th:({children:r,isHeader:o})=>o?e.jsx(t.MarkdownTh,{children:r}):e.jsx(t.MarkdownTd,{children:r}),pre:({children:r})=>e.jsx("pre",{children:r}),code:({children:r,inline:o,className:n})=>o?e.jsx(t.MarkdownCode,{children:r}):e.jsx(q.CodeBlock,{className:n,onCopy:h,children:r}),sub:({children:r})=>typeof r=="string"&&(r.startsWith(" ")||r.endsWith(" "))?e.jsxs(e.Fragment,{children:["~",r,"~"]}):e.jsx("sub",{children:r}),sup:({children:r})=>{if(r&&typeof r=="string"){const o=m?.find(n=>(n.data?.artifactSummary?.title||n.data?.name)===r);if(o){const n=o.data,s=n?.artifactSummary?.url,a=n?.artifactSummary?.title;if(!s)return null;const i=a||n?.name||r;return e.jsx(t.MarkdownSup,{children:e.jsx(t.MarkdownLink,{href:s,isExternal:c,onClick:()=>d?.(s,i),children:e.jsx("span",{children:i})})})}}return e.jsx("sup",{children:r})}}),[c,d,h,m]);if(!u)return null;const w=e.jsx(f,{remarkPlugins:C,rehypePlugins:v,components:M,disallowedElements:R,children:u.toString(),...p});return e.jsx(S.ChatMarkdownProvider,{componentStyles:k,children:w})});j.displayName="Markdown";const R=["script","iframe","frame","embed","meta","base","form","style","object"];exports.Markdown=j;
@@ -1,4 +1,4 @@
1
- import { ComponentPropsWithRef } from 'react';
1
+ import { default as React } from 'react';
2
2
  import { CodeProps } from '../codeblock';
3
3
  import { MarkdownComponentID } from '../../utils/component-ids';
4
4
  import { ArtifactPart } from '../../../types/index.ts';
@@ -14,4 +14,16 @@ export interface MarkdownProps {
14
14
  onLinkClick?: (href: string | undefined, label: string | undefined) => void;
15
15
  artifacts?: ArtifactPart[];
16
16
  }
17
- export declare const Markdown: ({ children, componentStyles, shouldOpenLinksInNewTab, onLinkClick, onCodeCopy, artifacts, ...props }: ComponentPropsWithRef<"div"> & MarkdownProps) => import("react/jsx-runtime").JSX.Element | null;
17
+ /**
18
+ * react-markdown does no memoization of its own: it builds a fresh unified
19
+ * processor and runs a full parse + rehype pass in its render body on every
20
+ * render (rehype-raw in particular re-serializes and re-parses the tree). In a
21
+ * streaming chat that means every already-complete message re-parses its whole
22
+ * body on every token, so cost grows with conversation length.
23
+ *
24
+ * `memo` is what prevents that: messages that are not currently streaming pass
25
+ * an unchanged `text` and memoized callbacks, so they bail out before any
26
+ * parsing happens. Keep the props passed here referentially stable at the call
27
+ * site or the memo is defeated and the parse comes back.
28
+ */
29
+ export declare const Markdown: React.NamedExoticComponent<React.ClassAttributes<HTMLDivElement> & React.HTMLAttributes<HTMLDivElement> & MarkdownProps>;
@@ -1,113 +1,119 @@
1
- import { jsx as t, jsxs as M, Fragment as y } from "react/jsx-runtime";
2
- import g from "react";
3
- import b from "react-markdown";
4
- import S from "rehype-raw";
5
- import C from "remark-gfm";
6
- import x from "remark-supersub";
7
- import { ChatMarkdownProvider as P } from "../../providers/markdown-provider.js";
8
- import { CodeBlock as j } from "../codeblock/index.js";
9
- import { MarkdownSup as E, MarkdownLink as m, MarkdownCode as H, MarkdownTh as R, MarkdownTd as T, MarkdownTable as v, MarkdownImg as A, MarkdownSourceLink as I, MarkdownOl as W, MarkdownInput as _, MarkdownHr as B, MarkdownUl as D, MarkdownLi as F, MarkdownP as G, MarkdownH2 as L, MarkdownH1 as U } from "./components.js";
10
- import { rehypeInlineCodeProperty as V } from "./rehype-inline-code-property.js";
11
- const rr = ({
12
- children: d,
13
- componentStyles: h,
14
- shouldOpenLinksInNewTab: l,
1
+ import { jsx as t, jsxs as w, Fragment as y } from "react/jsx-runtime";
2
+ import g, { memo as b, useMemo as S } from "react";
3
+ import x from "react-markdown";
4
+ import C from "rehype-raw";
5
+ import P from "remark-gfm";
6
+ import j from "remark-supersub";
7
+ import { ChatMarkdownProvider as E } from "../../providers/markdown-provider.js";
8
+ import { CodeBlock as H } from "../codeblock/index.js";
9
+ import { MarkdownSup as R, MarkdownLink as h, MarkdownCode as v, MarkdownTh as A, MarkdownTd as T, MarkdownTable as W, MarkdownImg as _, MarkdownSourceLink as B, MarkdownOl as D, MarkdownInput as F, MarkdownHr as G, MarkdownUl as I, MarkdownLi as U, MarkdownP as V, MarkdownH2 as $, MarkdownH1 as q } from "./components.js";
10
+ import { rehypeInlineCodeProperty as z } from "./rehype-inline-code-property.js";
11
+ const J = [[P, { singleTilde: !1 }], j], K = [C, z], Q = b(function({
12
+ children: l,
13
+ componentStyles: f,
14
+ shouldOpenLinksInNewTab: d,
15
15
  onLinkClick: c,
16
- onCodeCopy: u,
17
- artifacts: f,
16
+ onCodeCopy: s,
17
+ artifacts: m,
18
18
  ...p
19
- }) => {
20
- if (!d) return null;
21
- const k = {
22
- h1: ({ children: r }) => /* @__PURE__ */ t(U, { children: r }),
23
- h2: ({ children: r }) => /* @__PURE__ */ t(L, { children: r }),
24
- p: ({ children: r }) => /* @__PURE__ */ t(G, { children: r }),
25
- li: ({ children: r }) => /* @__PURE__ */ t(F, { children: r }),
26
- ul: ({ children: r }) => /* @__PURE__ */ t(D, { children: r }),
27
- hr: () => /* @__PURE__ */ t(B, {}),
28
- input: ({ type: r, checked: e, disabled: n, readOnly: o, required: a, value: i }) => /* @__PURE__ */ t(
29
- _,
30
- {
31
- type: r,
32
- checked: e,
33
- disabled: n,
34
- readOnly: o,
35
- required: a,
36
- value: i
37
- }
38
- ),
39
- ol: ({ children: r, node: e }) => {
40
- const n = e?.properties?.start, o = typeof n == "number" ? n : void 0;
41
- return /* @__PURE__ */ t(
42
- W,
43
- {
44
- style: {
45
- "--start": n?.toString() ?? "0"
46
- },
47
- start: o,
48
- children: r
49
- }
50
- );
51
- },
52
- a: ({ children: r, href: e }) => {
53
- const n = g.Children.toArray(r), o = n[0], a = typeof o == "string" && /^\(\d+\)$/.test(o) && n.length === 1, i = a ? o.match(/\d+/) : r, s = /* @__PURE__ */ t(
54
- m,
19
+ }) {
20
+ const k = S(
21
+ () => ({
22
+ h1: ({ children: r }) => /* @__PURE__ */ t(q, { children: r }),
23
+ h2: ({ children: r }) => /* @__PURE__ */ t($, { children: r }),
24
+ p: ({ children: r }) => /* @__PURE__ */ t(V, { children: r }),
25
+ li: ({ children: r }) => /* @__PURE__ */ t(U, { children: r }),
26
+ ul: ({ children: r }) => /* @__PURE__ */ t(I, { children: r }),
27
+ hr: () => /* @__PURE__ */ t(G, {}),
28
+ input: ({ type: r, checked: e, disabled: n, readOnly: o, required: a, value: i }) => /* @__PURE__ */ t(
29
+ F,
55
30
  {
56
- isExternal: l,
57
- href: e,
58
- onClick: () => {
59
- c?.(e, i?.toString());
60
- },
61
- children: i
31
+ type: r,
32
+ checked: e,
33
+ disabled: n,
34
+ readOnly: o,
35
+ required: a,
36
+ value: i
62
37
  }
63
- );
64
- return a ? /* @__PURE__ */ t(I, { children: s }) : s;
65
- },
66
- img: ({ src: r, alt: e }) => /* @__PURE__ */ t(A, { src: r, alt: e }),
67
- table: ({ children: r }) => /* @__PURE__ */ t(v, { children: r }),
68
- th: ({ children: r, isHeader: e }) => e ? /* @__PURE__ */ t(R, { children: r }) : /* @__PURE__ */ t(T, { children: r }),
69
- pre: ({ children: r }) => /* @__PURE__ */ t("pre", { children: r }),
70
- code: ({ children: r, inline: e, className: n }) => e ? /* @__PURE__ */ t(H, { children: r }) : /* @__PURE__ */ t(j, { className: n, onCopy: u, children: r }),
71
- sub: ({ children: r }) => typeof r == "string" && (r.startsWith(" ") || r.endsWith(" ")) ? /* @__PURE__ */ M(y, { children: [
72
- "~",
73
- r,
74
- "~"
75
- ] }) : /* @__PURE__ */ t("sub", { children: r }),
76
- sup: ({ children: r }) => {
77
- if (r && typeof r == "string") {
78
- const e = f?.find(
79
- (n) => (n.data?.artifactSummary?.title || n.data?.name) === r
38
+ ),
39
+ ol: ({ children: r, node: e }) => {
40
+ const n = e?.properties?.start, o = typeof n == "number" ? n : void 0;
41
+ return /* @__PURE__ */ t(
42
+ D,
43
+ {
44
+ style: {
45
+ "--start": n?.toString() ?? "0"
46
+ },
47
+ start: o,
48
+ children: r
49
+ }
80
50
  );
81
- if (e) {
82
- const n = e.data, o = n?.artifactSummary?.url, a = n?.artifactSummary?.title;
83
- if (!o) return null;
84
- const i = a || n?.name || r;
85
- return /* @__PURE__ */ t(E, { children: /* @__PURE__ */ t(
86
- m,
87
- {
88
- href: o,
89
- isExternal: l,
90
- onClick: () => c?.(o, i),
91
- children: /* @__PURE__ */ t("span", { children: i })
92
- }
93
- ) });
51
+ },
52
+ a: ({ children: r, href: e }) => {
53
+ const n = g.Children.toArray(r), o = n[0], a = typeof o == "string" && /^\(\d+\)$/.test(o) && n.length === 1, i = a ? o.match(/\d+/) : r, u = /* @__PURE__ */ t(
54
+ h,
55
+ {
56
+ isExternal: d,
57
+ href: e,
58
+ onClick: () => {
59
+ c?.(e, i?.toString());
60
+ },
61
+ children: i
62
+ }
63
+ );
64
+ return a ? /* @__PURE__ */ t(B, { children: u }) : u;
65
+ },
66
+ img: ({ src: r, alt: e }) => /* @__PURE__ */ t(_, { src: r, alt: e }),
67
+ table: ({ children: r }) => /* @__PURE__ */ t(W, { children: r }),
68
+ th: ({ children: r, isHeader: e }) => e ? /* @__PURE__ */ t(A, { children: r }) : /* @__PURE__ */ t(T, { children: r }),
69
+ pre: ({ children: r }) => /* @__PURE__ */ t("pre", { children: r }),
70
+ code: ({ children: r, inline: e, className: n }) => e ? /* @__PURE__ */ t(v, { children: r }) : /* @__PURE__ */ t(H, { className: n, onCopy: s, children: r }),
71
+ sub: ({ children: r }) => typeof r == "string" && (r.startsWith(" ") || r.endsWith(" ")) ? /* @__PURE__ */ w(y, { children: [
72
+ "~",
73
+ r,
74
+ "~"
75
+ ] }) : /* @__PURE__ */ t("sub", { children: r }),
76
+ sup: ({ children: r }) => {
77
+ if (r && typeof r == "string") {
78
+ const e = m?.find(
79
+ (n) => (n.data?.artifactSummary?.title || n.data?.name) === r
80
+ );
81
+ if (e) {
82
+ const n = e.data, o = n?.artifactSummary?.url, a = n?.artifactSummary?.title;
83
+ if (!o) return null;
84
+ const i = a || n?.name || r;
85
+ return /* @__PURE__ */ t(R, { children: /* @__PURE__ */ t(
86
+ h,
87
+ {
88
+ href: o,
89
+ isExternal: d,
90
+ onClick: () => c?.(o, i),
91
+ children: /* @__PURE__ */ t("span", { children: i })
92
+ }
93
+ ) });
94
+ }
94
95
  }
96
+ return /* @__PURE__ */ t("sup", { children: r });
95
97
  }
96
- return /* @__PURE__ */ t("sup", { children: r });
97
- }
98
- }, w = /* @__PURE__ */ t(
99
- b,
98
+ }),
99
+ [d, c, s, m]
100
+ );
101
+ if (!l) return null;
102
+ const M = /* @__PURE__ */ t(
103
+ x,
100
104
  {
101
- remarkPlugins: [[C, { singleTilde: !1 }], x],
102
- rehypePlugins: [S, V],
105
+ remarkPlugins: J,
106
+ rehypePlugins: K,
103
107
  components: k,
104
- disallowedElements: $,
105
- children: d.toString(),
108
+ disallowedElements: X,
109
+ children: l.toString(),
106
110
  ...p
107
111
  }
108
112
  );
109
- return /* @__PURE__ */ t(P, { componentStyles: h, children: w });
110
- }, $ = [
113
+ return /* @__PURE__ */ t(E, { componentStyles: f, children: M });
114
+ });
115
+ Q.displayName = "Markdown";
116
+ const X = [
111
117
  "script",
112
118
  "iframe",
113
119
  "frame",
@@ -119,5 +125,5 @@ const rr = ({
119
125
  "object"
120
126
  ];
121
127
  export {
122
- rr as Markdown
128
+ Q as Markdown
123
129
  };
@@ -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 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..
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("../../hooks/use-inkeep-api-client.cjs");function n(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 E(t){const e=n(t),r=o.parseAuthError(e??0,{detail:t.message??""});return r!==null?r:e===401?"session":e===403?"captcha":null}function a(t){const e=n(t);return e===400||e===413||e===429}function i(t){if(n(t)!==null)return!1;const e=(t.message??"").toLowerCase();return e.includes("failed to fetch")||e.includes("load failed")||e.includes("networkerror")||e.includes("network request failed")}const u="Something went wrong sending your message. Check your connection and try again.",c="Your message could not be sent. If you attached large files, try removing one. Otherwise, check your connection and try again.",_=`Hmm..
2
2
 
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;
3
+ It seems I might be having some issues right now. Please clear the chat and try again.`,l="Please try again.",R="You're sending requests too quickly. Please wait a moment and try again.",A="Your message or attachments are too large. Remove a file or shorten your message and try again.",S=43e5,s=4/3;function d(t){return new TextEncoder().encode(t.text).length+Math.ceil(t.rawFileBytes*s)+t.encodedPartsBytes}const O=8e3;exports.BASE64_SIZE_FACTOR=s;exports.DEFAULT_ERROR_MESSAGE=_;exports.MAX_REQUEST_BODY_BYTES=S;exports.NETWORK_ERROR_MESSAGE=u;exports.NETWORK_ERROR_WITH_FILES_MESSAGE=c;exports.PAYLOAD_TOO_LARGE_MESSAGE=A;exports.RATE_LIMIT_MESSAGE=R;exports.RECOVERABLE_FALLBACK_MESSAGE=l;exports.RECOVERABLE_NOTIFICATION_DURATION_MS=O;exports.estimateRequestBodyBytes=d;exports.isNetworkError=i;exports.isRecoverableError=a;exports.resolveHttpStatusCode=n;exports.resolveStreamingAuthError=E;
@@ -18,10 +18,47 @@ export declare function resolveStreamingAuthError(error: Error): 'captcha' | 'se
18
18
  * Recoverable errors are input-validation failures where the user can fix
19
19
  * their input and retry without clearing the conversation.
20
20
  *
21
+ * 413 (payload too large) is recoverable: the conversation is intact and the
22
+ * user can remove an attachment or shorten their message and resend.
23
+ *
21
24
  * Allowlist approach: unknown/unparseable errors default to non-recoverable (blocking).
22
25
  */
23
26
  export declare function isRecoverableError(error: Error): boolean;
27
+ /**
28
+ * Detects an opaque transport failure that arrived with no readable HTTP status —
29
+ * the fetch rejected before (or without) a usable response.
30
+ *
31
+ * The most common production cause is a platform-level 413: Vercel rejects any
32
+ * request body over ~4.5MB at the edge (base64-encoded file attachments inflate
33
+ * ~33%, so this is easy to hit), and that platform 413 carries no CORS headers
34
+ * because the app's cors() middleware never runs on it. The browser therefore
35
+ * blocks JS from reading the response and surfaces `TypeError: Failed to fetch`
36
+ * with no status. Genuine offline/DNS failures land here too — in both cases the
37
+ * conversation is intact and the user should get a non-blocking retry prompt.
38
+ *
39
+ * Matched on message signature (not error.name) so we don't swallow genuine
40
+ * programming TypeErrors as recoverable network failures.
41
+ */
42
+ export declare function isNetworkError(error: Error): boolean;
43
+ export declare const NETWORK_ERROR_MESSAGE = "Something went wrong sending your message. Check your connection and try again.";
44
+ export declare const NETWORK_ERROR_WITH_FILES_MESSAGE = "Your message could not be sent. If you attached large files, try removing one. Otherwise, check your connection and try again.";
24
45
  export declare const DEFAULT_ERROR_MESSAGE = "Hmm.. \n\nIt seems I might be having some issues right now. Please clear the chat and try again.";
25
46
  export declare const RECOVERABLE_FALLBACK_MESSAGE = "Please try again.";
26
47
  export declare const RATE_LIMIT_MESSAGE = "You're sending requests too quickly. Please wait a moment and try again.";
48
+ export declare const PAYLOAD_TOO_LARGE_MESSAGE = "Your message or attachments are too large. Remove a file or shorten your message and try again.";
49
+ export declare const MAX_REQUEST_BODY_BYTES = 4300000;
50
+ export declare const BASE64_SIZE_FACTOR: number;
51
+ /**
52
+ * Estimates the encoded byte size of the outgoing chat request body. Only the latest
53
+ * message is ever sent (the backend tracks history via conversationId), so file
54
+ * attachments in the current turn dominate — conversation history is irrelevant here.
55
+ */
56
+ export declare function estimateRequestBodyBytes(input: {
57
+ /** Message text. */
58
+ text: string;
59
+ /** Sum of `File.size` for freshly attached files (raw, pre-base64). */
60
+ rawFileBytes: number;
61
+ /** Sum of `.url.length` for already-encoded FileUIParts (data URLs). */
62
+ encodedPartsBytes: number;
63
+ }): number;
27
64
  export declare const RECOVERABLE_NOTIFICATION_DURATION_MS = 8000;
@@ -1,32 +1,51 @@
1
1
  "use client";
2
2
  import { parseAuthError as r } from "../../hooks/use-inkeep-api-client.js";
3
- function n(t) {
3
+ function s(t) {
4
4
  const e = Number(t.code) || Number(t.statusCode);
5
5
  if (e && !Number.isNaN(e)) return e;
6
6
  try {
7
- const s = Number(JSON.parse(t.message ?? "").status);
8
- return s && !Number.isNaN(s) ? s : null;
7
+ const n = Number(JSON.parse(t.message ?? "").status);
8
+ return n && !Number.isNaN(n) ? n : null;
9
9
  } catch {
10
10
  return null;
11
11
  }
12
12
  }
13
- function o(t) {
14
- const e = n(t), s = r(e ?? 0, { detail: t.message ?? "" });
15
- return s !== null ? s : e === 401 ? "session" : e === 403 ? "captcha" : null;
13
+ function c(t) {
14
+ const e = s(t), n = r(e ?? 0, { detail: t.message ?? "" });
15
+ return n !== null ? n : e === 401 ? "session" : e === 403 ? "captcha" : null;
16
+ }
17
+ function i(t) {
18
+ const e = s(t);
19
+ return e === 400 || e === 413 || e === 429;
16
20
  }
17
21
  function u(t) {
18
- const e = n(t);
19
- return e === 400 || e === 429;
22
+ if (s(t) !== null) return !1;
23
+ const e = (t.message ?? "").toLowerCase();
24
+ return e.includes("failed to fetch") || // Chromium
25
+ e.includes("load failed") || // Safari
26
+ e.includes("networkerror") || // Firefox
27
+ e.includes("network request failed");
20
28
  }
21
- const i = `Hmm..
29
+ const l = "Something went wrong sending your message. Check your connection and try again.", E = "Your message could not be sent. If you attached large files, try removing one. Otherwise, check your connection and try again.", d = `Hmm..
22
30
 
23
- It seems I might be having some issues right now. Please clear the chat and try again.`, c = "Please try again.", l = "You're sending requests too quickly. Please wait a moment and try again.", m = 8e3;
31
+ It seems I might be having some issues right now. Please clear the chat and try again.`, m = "Please try again.", g = "You're sending requests too quickly. Please wait a moment and try again.", R = "Your message or attachments are too large. Remove a file or shorten your message and try again.", _ = 43e5, o = 4 / 3;
32
+ function A(t) {
33
+ return new TextEncoder().encode(t.text).length + Math.ceil(t.rawFileBytes * o) + t.encodedPartsBytes;
34
+ }
35
+ const S = 8e3;
24
36
  export {
25
- i as DEFAULT_ERROR_MESSAGE,
26
- l as RATE_LIMIT_MESSAGE,
27
- c as RECOVERABLE_FALLBACK_MESSAGE,
28
- m as RECOVERABLE_NOTIFICATION_DURATION_MS,
29
- u as isRecoverableError,
30
- n as resolveHttpStatusCode,
31
- o as resolveStreamingAuthError
37
+ o as BASE64_SIZE_FACTOR,
38
+ d as DEFAULT_ERROR_MESSAGE,
39
+ _ as MAX_REQUEST_BODY_BYTES,
40
+ l as NETWORK_ERROR_MESSAGE,
41
+ E as NETWORK_ERROR_WITH_FILES_MESSAGE,
42
+ R as PAYLOAD_TOO_LARGE_MESSAGE,
43
+ g as RATE_LIMIT_MESSAGE,
44
+ m as RECOVERABLE_FALLBACK_MESSAGE,
45
+ S as RECOVERABLE_NOTIFICATION_DURATION_MS,
46
+ A as estimateRequestBodyBytes,
47
+ u as isNetworkError,
48
+ i as isRecoverableError,
49
+ s as resolveHttpStatusCode,
50
+ c as resolveStreamingAuthError
32
51
  };
@@ -1,2 +1,2 @@
1
- "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Ze=require("@ai-sdk/react"),Xe=require("./file-upload-input.cjs"),Ye=require("ai"),t=require("react"),et=require("../../providers/config-provider.cjs"),tt=require("../../providers/chat-auth-provider.cjs"),st=require("../../hooks/use-media-query.cjs"),rt=require("../../hooks/use-conversation-loader.cjs"),nt=require("../../hooks/use-initial-conversation.cjs"),k=require("../../utils/generate-uid.cjs"),at=require("../../providers/base-events-provider.cjs"),ot=require("../../providers/chat-form-provider.cjs"),it=require("../../providers/widget-provider.cjs"),ct=require("@radix-ui/react-use-controllable-state"),ut=require("../../hooks/use-streaming-events.cjs"),lt=require("../../hooks/use-input-notification.cjs"),f=require("./chat-error-helpers.cjs"),dt=()=>{const{baseSettings:se,aiChatSettings:m}=et.useInkeepConfig(),[c="",v]=ct.useControllableState({prop:m.conversationIdOverride,defaultProp:m.conversationIdOverride??""}),{logEvent:h}=at.useBaseEvents(),{setConversationId:ke,emitToParent:F}=ut.useStreamingEvents(),re=t.useRef(c);t.useEffect(()=>{const e=re.current;re.current=c,e!==c&&h({eventName:"chat_conversation_changed",properties:{conversationId:c,previousConversationId:e}})},[c,h]);const[S,I]=t.useState(""),Fe=e=>I(e.target.value),{shouldBypassCaptcha:_e,filters:ne,userProperties:N,analyticsProperties:O}=se,{authToken:ae,isAuthenticated:y,isAuthConfigured:oe,refreshAuthToken:ie,sessionToken:ce,refreshSession:ue,getCaptchaHeader:_,invalidateCaptcha:d,effectiveAuthToken:le,applicableRefreshSession:Pe}=tt.useChatAuth(),{onInputMessageChange:xe,filters:de,baseUrl:fe,agentUrl:qe,context:pe,headers:ge,appId:P,apiKey:U,files:A}=m,he=t.useRef(_);he.current=_;const me=qe||`${fe}/run/api/chat`,{loadConversation:ve}=rt.useConversationLoader({baseUrl:fe,appId:P,authToken:le,getCaptchaHeader:_,invalidateCaptcha:d,refreshSession:Pe}),[Le,ye]=t.useState(!1),D=t.useRef(null);D.current=ce;const $=t.useRef(null);$.current=ae;const B=t.useRef(void 0);B.current=N&&Object.keys(N).length>0?N:void 0;const G=t.useRef(void 0);G.current=O&&Object.keys(O).length>0?O:void 0;const R=t.useRef(0),H=t.useRef(null),K=t.useRef(null),C=t.useRef(void 0),Ne=A?.map(e=>`${e.filename??""}:${e.mediaType}:${e.url.length}:${e.url.slice(0,64)}:${e.url.slice(-32)}`).join(`
2
- `)??"";t.useEffect(()=>{C.current=A?.length?A:void 0},[Ne]);const Re=t.useRef(ge);Re.current=ge;const z=t.useRef(void 0);z.current=ne||de?JSON.stringify({...ne,...de}):void 0;const Oe=e=>{switch(f.resolveHttpStatusCode(e)){case 400:try{const s=JSON.parse(e.message??"");return s.detail??s.error?.message??f.RECOVERABLE_FALLBACK_MESSAGE}catch{return e.message?.trim()||f.RECOVERABLE_FALLBACK_MESSAGE}case 401:return oe?"Authentication failed. Please try again.":f.DEFAULT_ERROR_MESSAGE;case 403:return`There seems to be a configuration error. Please contact ${se.organizationDisplayName??"Administrator"}`;case 429:return f.RATE_LIMIT_MESSAGE;default:return f.DEFAULT_ERROR_MESSAGE}},[b,j]=t.useState([]),Ue=t.useMemo(()=>new Ye.DefaultChatTransport({api:me,headers:()=>{const e=U??$.current??D.current;return{"x-inkeep-client-timezone":Intl.DateTimeFormat().resolvedOptions().timeZone,"x-inkeep-client-timestamp":new Date().toISOString(),"x-inkeep-invocation-type":"chat_widget",...P?{"x-inkeep-app-id":P}:{},...e?{Authorization:`Bearer ${e}`}:{},...z.current?{"inkeep-filters":z.current}:{},...Re.current}},prepareSendMessagesRequest:async e=>{const a=await he.current(),s=e.messages[e.messages.length-1];return s||console.warn("[useInkeepChat] prepareSendMessagesRequest called with empty messages array"),{body:{...e.body,id:e.id,messages:s?[s]:[],trigger:e.trigger,messageId:e.messageId,...B.current?{userProperties:B.current}:{},...G.current?{properties:G.current}:{}},headers:{...e.headers,...a}}},body:{requestContext:pe}}),[me,pe,P,U]),{messages:w,sendMessage:V,addToolApprovalResponse:J,status:Ce,setMessages:p,stop:x,error:q}=Ze.useChat({transport:Ue,onData(e){F(e.type,e.data)},async onFinish({message:e}){F("completion",{conversationId:c}),await h({eventName:"assistant_message_received",properties:{conversationId:c,messageId:e.id}}),h({eventName:"assistant_answer_displayed",properties:{conversationId:c,messageId:e.id}})},onError(e){console.error("onError",{code:e.code,message:e.message});const a=_e||U?null:f.resolveStreamingAuthError(e);if(a!==null&&R.current<1){R.current++;const n=K.current,r=H.current;(async()=>{if(a==="session"&&oe){const l=await ie();if(!l)throw new Error("Auth token refresh failed");$.current=l}else if(a==="session"){const l=await ue();l&&(D.current=l)}else d();if(n){J(n);return}r&&(p(l=>{let o=[...l];return o.at(-1)?.role==="assistant"&&(o=o.slice(0,-1)),o.at(-1)?.role==="user"&&(o=o.slice(0,-1)),o}),V({id:r.messageId,parts:[...r.content.trim()?[{type:"text",text:r.content}]:[],...r.files??[]]},{body:r.body}))})().catch(()=>{R.current=0,d(),p(l=>{const o=[...l],g=o[o.length-1];if(!g)return o;const L=f.DEFAULT_ERROR_MESSAGE;return g.role==="user"?o.push({id:k.generateUid(16),role:"assistant",parts:[{type:"text",text:L}]}):g.parts=[{type:"text",text:L}],o})});return}R.current=0,a!==null&&d();const s=f.isRecoverableError(e),u=Oe(e);if(h({eventName:"chat_error",properties:{conversationId:c,messageId:w.at(-1)?.id,error:e.message}}),s){Y({title:"Request failed",message:u},f.RECOVERABLE_NOTIFICATION_DURATION_MS),p(r=>{let i=[...r];return i.at(-1)?.role==="assistant"&&(i=i.slice(0,-1)),i.at(-1)?.role==="user"&&(i=i.slice(0,-1)),i});const n=H.current?.content;n&&I(n),X.current=e;return}p(n=>{const r=[...n],i=r[r.length-1];return i&&(i.role==="user"?r.push({id:k.generateUid(16),role:"assistant",parts:[{type:"text",text:u}]}):i.parts=[{type:"text",text:u}]),r})}}),Ee=t.useRef(y);t.useEffect(()=>{const e=Ee.current;Ee.current=y,e!==y&&(x(),M(null),p([]),v(""),I(""),j([]),d())},[y,x,p,v,d]);const Se=Ce==="submitted",Q=Ce==="streaming",De=t.useMemo(()=>{const e=n=>{if(!n||typeof n!="object")return!1;const r=n;return typeof r.type=="string"&&r.type.startsWith("tool-")},s=[...w??[]].reverse().find(n=>n.role==="assistant");if(!s)return!1;const u=s.parts?.at(-1);return!(!e(u)||u.state!=="output-available"||!u.approval?.id||Q)},[w,Q]),[$e,W]=t.useState(!1),Ie=Q||De&&!$e,Ae=Se||Ie,Be=w.length===0,Z=!S.trim()&&b.length===0||Ae,Ge=st.useMediaQuery("(max-width: 768px)"),[He,M]=t.useState(null),X=t.useRef(null);t.useEffect(()=>{if(q){if(X.current===q){X.current=null;return}M(q)}},[q]);const Ke=()=>M(null),{inputNotification:ze,showInputNotification:Y,clearInputNotification:je}=lt.useInputNotification(),be=t.useRef(null);t.useEffect(()=>{xe?.(S)},[S]);const Ve=e=>{e.key==="Enter"&&!e.shiftKey&&!Z&&!e.nativeEvent.isComposing&&(e.preventDefault(),ee())},ee=async(e=S)=>{if(Z&&(!e||e.trim().length===0)&&b.length===0||!e.trim()&&!b.length&&!C.current?.length)return;const a=b;j([]),I(""),R.current=0,K.current=null,W(!1);let s=c;s||(s=`conv_${k.generateUid(16)}`,v(s));const u=k.generateUid(21);ke(s),await h({eventName:"user_message_submitted",properties:{conversationId:s,messageId:u}});const n=C.current;C.current=void 0;let r=[];if(a.length>0)try{r=await Promise.all(a.map(o=>{const g=Xe.normalizeFileType(o);return new Promise((L,Te)=>{const T=new FileReader;T.onload=()=>{if(typeof T.result!="string"){Te(new Error(`Failed to read file "${g.name}"`));return}L({type:"file",url:T.result,mediaType:g.type,filename:g.name})},T.onerror=()=>Te(new Error(`Failed to read file "${g.name}"`)),T.readAsDataURL(g)})}))}catch{Y({title:"Failed to attach files",message:"Could not read one or more files. Please try again."});return}const i=r.length||n?.length?[...r,...n??[]]:void 0,l=[...e.trim()?[{type:"text",text:e}]:[],...i??[]];H.current={content:e,messageId:u,body:{conversationId:s},files:i},V({id:u,parts:l},{body:{conversationId:s}})},Je=t.useCallback(e=>{R.current=0,K.current=e,W(!1),J(e)},[J]),te=t.useCallback(()=>{W(!0),x().then(()=>{F("aborted",{conversationId:c})})},[x,c,F]),we=()=>{Ke(),p([]),v(""),d(),C.current=A?.length?A:void 0,h({eventName:"chat_clear_button_clicked",properties:{conversationId:c}})},E=t.useCallback((e,a)=>{M(null),p(a),v(e),d(),C.current=void 0},[p,v,d]),Me=t.useCallback(async(e,a)=>{te(),E(e,[]),ye(!0);try{const s=await ve(e,a);if(s===null)return!1;const n=s[s.length-1]?.role==="user"?[...s,{id:k.generateUid(16),role:"assistant",parts:[{type:"text",text:"This session was interrupted. Please check back in a few minutes or start a new conversation."}]}]:s;return E(e,n),!0}finally{a?.aborted||ye(!1)}},[E,ve,te]);nt.useInitialConversation({conversationId:m.conversationId,fetchedConversation:m.fetchedConversation,effectiveAuthToken:le,restoreSession:E,loadAndRestoreSession:Me,onLoadFailed:()=>E("",[])});const{openForm:Qe}=ot.useChatForm(),We=it.useWidget();return t.useImperativeHandle(m.chatFunctionsRef,()=>({submitMessage:ee,updateInputMessage(e){I(e)},clearChat:we,openForm:e=>{We?.setView("chat"),Qe(e,void 0)},focusInput:()=>{be.current?.focus()}})),{messages:w,sendMessage:V,addToolApprovalResponse:Je,isLoading:Se,isStreaming:Ie,isBusy:Ae,error:He,setError:M,isSubmitDisabled:Z,input:S,handleInputChange:Fe,handleInputKeyDown:Ve,handleSubmit:ee,stop:te,clear:we,inputRef:be,isMobile:Ge,files:b,setFiles:j,isNewChat:Be,conversationId:c,restoreSession:E,loadAndRestoreSession:Me,isSessionLoading:Le,authToken:y?ae:ce,refreshSession:y?ie:ue,getCaptchaHeader:_,invalidateCaptcha:d,inputNotification:ze,showInputNotification:Y,clearInputNotification:je}};exports.useInkeepChat=dt;
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Xe=require("@ai-sdk/react"),Ze=require("./file-upload-input.cjs"),et=require("ai"),t=require("react"),tt=require("../../providers/config-provider.cjs"),st=require("../../providers/chat-auth-provider.cjs"),rt=require("../../hooks/use-media-query.cjs"),nt=require("../../hooks/use-conversation-loader.cjs"),at=require("../../hooks/use-initial-conversation.cjs"),w=require("../../utils/generate-uid.cjs"),ot=require("../../providers/base-events-provider.cjs"),it=require("../../providers/chat-form-provider.cjs"),ct=require("../../providers/widget-provider.cjs"),ut=require("@radix-ui/react-use-controllable-state"),lt=require("../../hooks/use-streaming-events.cjs"),dt=require("../../hooks/use-input-notification.cjs"),s=require("./chat-error-helpers.cjs"),ft=50,pt=()=>{const{baseSettings:se,aiChatSettings:R}=tt.useInkeepConfig(),[u="",v]=ut.useControllableState({prop:R.conversationIdOverride,defaultProp:R.conversationIdOverride??""}),{logEvent:m}=ot.useBaseEvents(),{setConversationId:Oe,emitToParent:k}=lt.useStreamingEvents(),re=t.useRef(u);t.useEffect(()=>{const e=re.current;re.current=u,e!==u&&m({eventName:"chat_conversation_changed",properties:{conversationId:u,previousConversationId:e}})},[u,m]);const[I,C]=t.useState(""),we=e=>C(e.target.value),{shouldBypassCaptcha:ke,filters:ne,userProperties:B,analyticsProperties:D}=se,{authToken:ae,isAuthenticated:S,isAuthConfigured:oe,refreshAuthToken:ie,sessionToken:ce,refreshSession:ue,getCaptchaHeader:F,invalidateCaptcha:f,effectiveAuthToken:le,applicableRefreshSession:Fe}=st.useChatAuth(),{onInputMessageChange:Le,filters:de,baseUrl:fe,agentUrl:Ne,context:pe,headers:ge,appId:L,apiKey:U,files:T}=R,he=t.useRef(F);he.current=F;const me=Ne||`${fe}/run/api/chat`,{loadConversation:Ee}=nt.useConversationLoader({baseUrl:fe,appId:L,authToken:le,getCaptchaHeader:F,invalidateCaptcha:f,refreshSession:Fe}),[Pe,Re]=t.useState(!1),G=t.useRef(null);G.current=ce;const $=t.useRef(null);$.current=ae;const K=t.useRef(void 0);K.current=B&&Object.keys(B).length>0?B:void 0;const H=t.useRef(void 0);H.current=D&&Object.keys(D).length>0?D:void 0;const y=t.useRef(0),N=t.useRef(null),W=t.useRef(null),E=t.useRef(void 0),xe=T?.map(e=>`${e.filename??""}:${e.mediaType}:${e.url.length}:${e.url.slice(0,64)}:${e.url.slice(-32)}`).join(`
2
+ `)??"";t.useEffect(()=>{E.current=T?.length?T:void 0},[xe]);const ve=t.useRef(ge);ve.current=ge;const z=t.useRef(void 0);z.current=ne||de?JSON.stringify({...ne,...de}):void 0;const qe=e=>{if(s.isNetworkError(e))return N.current?.files?.length?s.NETWORK_ERROR_WITH_FILES_MESSAGE:s.NETWORK_ERROR_MESSAGE;switch(s.resolveHttpStatusCode(e)){case 400:try{const n=JSON.parse(e.message??"");return n.detail??n.error?.message??s.RECOVERABLE_FALLBACK_MESSAGE}catch{return e.message?.trim()||s.RECOVERABLE_FALLBACK_MESSAGE}case 401:return oe?"Authentication failed. Please try again.":s.DEFAULT_ERROR_MESSAGE;case 403:return`There seems to be a configuration error. Please contact ${se.organizationDisplayName??"Administrator"}`;case 413:return s.PAYLOAD_TOO_LARGE_MESSAGE;case 429:return s.RATE_LIMIT_MESSAGE;default:return s.DEFAULT_ERROR_MESSAGE}},[A,V]=t.useState([]),Be=t.useMemo(()=>new et.DefaultChatTransport({api:me,headers:()=>{const e=U??$.current??G.current;return{"x-inkeep-client-timezone":Intl.DateTimeFormat().resolvedOptions().timeZone,"x-inkeep-client-timestamp":new Date().toISOString(),"x-inkeep-invocation-type":"chat_widget",...L?{"x-inkeep-app-id":L}:{},...e?{Authorization:`Bearer ${e}`}:{},...z.current?{"inkeep-filters":z.current}:{},...ve.current}},prepareSendMessagesRequest:async e=>{const l=await he.current(),n=e.messages[e.messages.length-1];return n||console.warn("[useInkeepChat] prepareSendMessagesRequest called with empty messages array"),{body:{...e.body,id:e.id,messages:n?[n]:[],trigger:e.trigger,messageId:e.messageId,...K.current?{userProperties:K.current}:{},...H.current?{properties:H.current}:{}},headers:{...e.headers,...l}}},body:{requestContext:pe}}),[me,pe,L,U]),{messages:M,sendMessage:Y,addToolApprovalResponse:j,status:Se,setMessages:h,stop:P,error:x}=Xe.useChat({transport:Be,experimental_throttle:ft,onData(e){k(e.type,e.data)},async onFinish({message:e}){k("completion",{conversationId:u}),await m({eventName:"assistant_message_received",properties:{conversationId:u,messageId:e.id}}),m({eventName:"assistant_answer_displayed",properties:{conversationId:u,messageId:e.id}})},onError(e){console.error("onError",{code:e.code,message:e.message});const l=ke||U?null:s.resolveStreamingAuthError(e);if(l!==null&&y.current<1){y.current++;const i=W.current,r=N.current;(async()=>{if(l==="session"&&oe){const o=await ie();if(!o)throw new Error("Auth token refresh failed");$.current=o}else if(l==="session"){const o=await ue();o&&(G.current=o)}else f();if(i){j(i);return}r&&(h(o=>{let c=[...o];return c.at(-1)?.role==="assistant"&&(c=c.slice(0,-1)),c.at(-1)?.role==="user"&&(c=c.slice(0,-1)),c}),Y({id:r.messageId,parts:[...r.content.trim()?[{type:"text",text:r.content}]:[],...r.files??[]]},{body:r.body}))})().catch(()=>{y.current=0,f(),h(o=>{const c=[...o],g=c[c.length-1];if(!g)return c;const d=s.DEFAULT_ERROR_MESSAGE;return g.role==="user"?c.push({id:w.generateUid(16),role:"assistant",parts:[{type:"text",text:d}]}):c[c.length-1]={...g,parts:[{type:"text",text:d}]},c})});return}y.current=0,l!==null&&f();const n=s.isRecoverableError(e)||s.isNetworkError(e),a=qe(e);if(m({eventName:"chat_error",properties:{conversationId:u,messageId:M.at(-1)?.id,error:e.message}}),n){const i=a===s.PAYLOAD_TOO_LARGE_MESSAGE?"Message too large":a===s.RATE_LIMIT_MESSAGE?"Rate limit reached":a===s.NETWORK_ERROR_MESSAGE||a===s.NETWORK_ERROR_WITH_FILES_MESSAGE?"Connection error":"Request failed";q({title:i,message:a},s.RECOVERABLE_NOTIFICATION_DURATION_MS),h(p=>{let o=[...p];return o.at(-1)?.role==="assistant"&&(o=o.slice(0,-1)),o.at(-1)?.role==="user"&&(o=o.slice(0,-1)),o});const r=N.current?.content;r&&C(r),Z.current=e;return}h(i=>{const r=[...i],p=r[r.length-1];return p&&(p.role==="user"?r.push({id:w.generateUid(16),role:"assistant",parts:[{type:"text",text:a}]}):r[r.length-1]={...p,parts:[{type:"text",text:a}]}),r})}}),ye=t.useRef(S);t.useEffect(()=>{const e=ye.current;ye.current=S,e!==S&&(P(),b(null),h([]),v(""),C(""),V([]),f())},[S,P,h,v,f]);const Ae=Se==="submitted",Q=Se==="streaming",De=t.useMemo(()=>{const e=i=>{if(!i||typeof i!="object")return!1;const r=i;return typeof r.type=="string"&&r.type.startsWith("tool-")},n=[...M??[]].reverse().find(i=>i.role==="assistant");if(!n)return!1;const a=n.parts?.at(-1);return!(!e(a)||a.state!=="output-available"||!a.approval?.id||Q)},[M,Q]),[Ue,J]=t.useState(!1),_e=Q||De&&!Ue,Ie=Ae||_e,Ge=M.length===0,X=!I.trim()&&A.length===0||Ie,$e=rt.useMediaQuery("(max-width: 768px)"),[Ke,b]=t.useState(null),Z=t.useRef(null);t.useEffect(()=>{if(x){if(Z.current===x){Z.current=null;return}b(x)}},[x]);const He=()=>b(null),{inputNotification:We,showInputNotification:q,clearInputNotification:ze}=dt.useInputNotification(),Ce=t.useRef(null);t.useEffect(()=>{Le?.(I)},[I]);const Ve=e=>{e.key==="Enter"&&!e.shiftKey&&!X&&!e.nativeEvent.isComposing&&(e.preventDefault(),ee())},ee=async(e=I)=>{if(X&&(!e||e.trim().length===0)&&A.length===0||!e.trim()&&!A.length&&!E.current?.length)return;if(s.estimateRequestBodyBytes({text:e,rawFileBytes:A.reduce((g,d)=>g+d.size,0),encodedPartsBytes:(E.current??[]).reduce((g,d)=>g+d.url.length,0)})>s.MAX_REQUEST_BODY_BYTES){q({title:"Message too large",message:s.PAYLOAD_TOO_LARGE_MESSAGE},s.RECOVERABLE_NOTIFICATION_DURATION_MS);return}const n=A;V([]),C(""),y.current=0,W.current=null,J(!1);let a=u;a||(a=`conv_${w.generateUid(16)}`,v(a));const i=w.generateUid(21);Oe(a),await m({eventName:"user_message_submitted",properties:{conversationId:a,messageId:i}});const r=E.current;E.current=void 0;let p=[];if(n.length>0)try{p=await Promise.all(n.map(g=>{const d=Ze.normalizeFileType(g);return new Promise((Je,be)=>{const O=new FileReader;O.onload=()=>{if(typeof O.result!="string"){be(new Error(`Failed to read file "${d.name}"`));return}Je({type:"file",url:O.result,mediaType:d.type,filename:d.name})},O.onerror=()=>be(new Error(`Failed to read file "${d.name}"`)),O.readAsDataURL(d)})}))}catch{q({title:"Failed to attach files",message:"Could not read one or more files. Please try again."});return}const o=p.length||r?.length?[...p,...r??[]]:void 0,c=[...e.trim()?[{type:"text",text:e}]:[],...o??[]];N.current={content:e,messageId:i,body:{conversationId:a},files:o},Y({id:i,parts:c},{body:{conversationId:a}})},Ye=t.useCallback(e=>{y.current=0,W.current=e,J(!1),j(e)},[j]),te=t.useCallback(()=>{J(!0),P().then(()=>{k("aborted",{conversationId:u})})},[P,u,k]),Te=()=>{He(),h([]),v(""),f(),E.current=T?.length?T:void 0,m({eventName:"chat_clear_button_clicked",properties:{conversationId:u}})},_=t.useCallback((e,l)=>{b(null),h(l),v(e),f(),E.current=void 0},[h,v,f]),Me=t.useCallback(async(e,l)=>{te(),_(e,[]),Re(!0);try{const n=await Ee(e,l);if(n===null)return!1;const i=n[n.length-1]?.role==="user"?[...n,{id:w.generateUid(16),role:"assistant",parts:[{type:"text",text:"This session was interrupted. Please check back in a few minutes or start a new conversation."}]}]:n;return _(e,i),!0}finally{l?.aborted||Re(!1)}},[_,Ee,te]);at.useInitialConversation({conversationId:R.conversationId,fetchedConversation:R.fetchedConversation,effectiveAuthToken:le,restoreSession:_,loadAndRestoreSession:Me,onLoadFailed:()=>_("",[])});const{openForm:je}=it.useChatForm(),Qe=ct.useWidget();return t.useImperativeHandle(R.chatFunctionsRef,()=>({submitMessage:ee,updateInputMessage(e){C(e)},clearChat:Te,openForm:e=>{Qe?.setView("chat"),je(e,void 0)},focusInput:()=>{Ce.current?.focus()}})),{messages:M,sendMessage:Y,addToolApprovalResponse:Ye,isLoading:Ae,isStreaming:_e,isBusy:Ie,error:Ke,setError:b,isSubmitDisabled:X,input:I,handleInputChange:we,handleInputKeyDown:Ve,handleSubmit:ee,stop:te,clear:Te,inputRef:Ce,isMobile:$e,files:A,setFiles:V,isNewChat:Ge,conversationId:u,restoreSession:_,loadAndRestoreSession:Me,isSessionLoading:Pe,authToken:S?ae:ce,refreshSession:S?ie:ue,getCaptchaHeader:F,invalidateCaptcha:f,inputNotification:We,showInputNotification:q,clearInputNotification:ze}};exports.useInkeepChat=pt;