@waniwani/sdk 0.0.10 → 0.0.13
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/chat/index.d.ts +77 -7
- package/dist/chat/index.js +1 -1
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/next-js/index.d.ts +178 -0
- package/dist/chat/next-js/index.js +2 -0
- package/dist/chat/next-js/index.js.map +1 -0
- package/dist/chat/server/index.d.ts +66 -0
- package/dist/chat/server/index.js +2 -0
- package/dist/chat/server/index.js.map +1 -0
- package/dist/chat/styles.css +1 -1
- package/dist/{chunk-SCDEAZN4.js → chunk-DGSC74SV.js} +1 -1
- package/dist/chunk-DGSC74SV.js.map +1 -0
- package/dist/{chunk-OVQDB7QX.js → chunk-ZUGQBRJF.js} +1 -1
- package/dist/chunk-ZUGQBRJF.js.map +1 -0
- package/dist/index.d.ts +15 -7
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.d.ts +267 -103
- package/dist/mcp/index.js +3 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/react.js +2 -2
- package/dist/mcp/react.js.map +1 -1
- package/dist/{mcp-apps-client-DZ3L5O3U.js → mcp-apps-client-GILGJJZP.js} +1 -1
- package/dist/mcp-apps-client-GILGJJZP.js.map +1 -0
- package/dist/{openai-client-UL6T463M.js → openai-client-3M6MDERR.js} +2 -2
- package/dist/openai-client-3M6MDERR.js.map +1 -0
- package/dist/platform-GKYYQBCS.js +3 -0
- package/package.json +17 -4
- package/dist/chunk-OVQDB7QX.js.map +0 -1
- package/dist/chunk-SCDEAZN4.js.map +0 -1
- package/dist/mcp-apps-client-DZ3L5O3U.js.map +0 -1
- package/dist/openai-client-UL6T463M.js.map +0 -1
- package/dist/platform-4QZXTYT5.js +0 -3
- /package/dist/{platform-4QZXTYT5.js.map → platform-GKYYQBCS.js.map} +0 -0
package/dist/chat/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
1
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
3
|
|
|
3
4
|
interface ChatTheme {
|
|
@@ -25,8 +26,20 @@ interface ChatTheme {
|
|
|
25
26
|
messageBorderRadius?: number;
|
|
26
27
|
/** Font family */
|
|
27
28
|
fontFamily?: string;
|
|
29
|
+
/** Header background color (card layout). Falls back to backgroundColor. */
|
|
30
|
+
headerBackgroundColor?: string;
|
|
31
|
+
/** Header text color. Falls back to textColor. */
|
|
32
|
+
headerTextColor?: string;
|
|
33
|
+
/** Status dot color. Defaults to green (#22c55e). */
|
|
34
|
+
statusColor?: string;
|
|
35
|
+
/** Tool call JSON section background. Defaults to light gray / #262626 in dark. */
|
|
36
|
+
toolCardColor?: string;
|
|
28
37
|
}
|
|
29
|
-
interface
|
|
38
|
+
interface SuggestionsConfig {
|
|
39
|
+
/** Maximum number of AI suggestions to request. Defaults to 3. */
|
|
40
|
+
count?: number;
|
|
41
|
+
}
|
|
42
|
+
interface ChatBaseProps {
|
|
30
43
|
/** WaniWani project API key */
|
|
31
44
|
apiKey?: string;
|
|
32
45
|
/** Chat API endpoint URL. Defaults to WaniWani hosted endpoint */
|
|
@@ -39,22 +52,79 @@ interface ChatWidgetProps {
|
|
|
39
52
|
headers?: Record<string, string>;
|
|
40
53
|
/** Additional body fields to send with each chat request */
|
|
41
54
|
body?: Record<string, unknown>;
|
|
42
|
-
/** Chat bar width in pixels. Defaults to 600. */
|
|
43
|
-
width?: number;
|
|
44
|
-
/** Max height of the expanded messages panel in pixels. Defaults to 400. */
|
|
45
|
-
expandedHeight?: number;
|
|
46
55
|
/** Enable file attachments in the input. Defaults to false. */
|
|
47
56
|
allowAttachments?: boolean;
|
|
48
57
|
/** Callback fired when a message is sent */
|
|
49
58
|
onMessageSent?: (message: string) => void;
|
|
50
59
|
/** Callback fired when a response is received */
|
|
51
60
|
onResponseReceived?: () => void;
|
|
61
|
+
/** Endpoint URL for fetching MCP app resources (HTML widgets). Defaults to "/api/mcp/resource" */
|
|
62
|
+
resourceEndpoint?: string;
|
|
63
|
+
/** Static suggestions shown before the user sends their first message */
|
|
64
|
+
initialSuggestions?: string[];
|
|
65
|
+
/**
|
|
66
|
+
* Enable AI-generated suggestions after each response.
|
|
67
|
+
* `true` enables with defaults (3 suggestions), object allows config, `false`/undefined disables.
|
|
68
|
+
*/
|
|
69
|
+
suggestions?: boolean | SuggestionsConfig;
|
|
70
|
+
}
|
|
71
|
+
interface ChatBarProps extends ChatBaseProps {
|
|
72
|
+
/** Chat bar width in pixels. Defaults to 600. */
|
|
73
|
+
width?: number;
|
|
74
|
+
/** Max height of the expanded messages panel in pixels. Defaults to 400. */
|
|
75
|
+
expandedHeight?: number;
|
|
76
|
+
}
|
|
77
|
+
interface ChatCardProps extends ChatBaseProps {
|
|
78
|
+
/** Title shown in the card header. Defaults to "Assistant". */
|
|
79
|
+
title?: string;
|
|
80
|
+
/** Subtitle or status text shown under the title. */
|
|
81
|
+
subtitle?: string;
|
|
82
|
+
/** Show the status dot in the header. Defaults to true. */
|
|
83
|
+
showStatus?: boolean;
|
|
84
|
+
/** Card width in pixels. Defaults to 400. */
|
|
85
|
+
width?: number;
|
|
86
|
+
/** Card height in pixels. Defaults to 600. */
|
|
87
|
+
height?: number;
|
|
88
|
+
}
|
|
89
|
+
interface ChatHandle {
|
|
90
|
+
/** Programmatically send a user message into the chat */
|
|
91
|
+
sendMessage: (text: string) => void;
|
|
92
|
+
}
|
|
93
|
+
/** @deprecated Use ChatBarProps instead */
|
|
94
|
+
type ChatWidgetProps = ChatBarProps;
|
|
95
|
+
|
|
96
|
+
declare const ChatBar: react.ForwardRefExoticComponent<ChatBarProps & react.RefAttributes<ChatHandle>>;
|
|
97
|
+
|
|
98
|
+
interface McpAppFrameProps {
|
|
99
|
+
resourceUri: string;
|
|
100
|
+
toolInput: Record<string, unknown>;
|
|
101
|
+
toolResult: {
|
|
102
|
+
content?: Array<{
|
|
103
|
+
type: string;
|
|
104
|
+
text?: string;
|
|
105
|
+
}>;
|
|
106
|
+
structuredContent?: Record<string, unknown>;
|
|
107
|
+
};
|
|
108
|
+
resourceEndpoint?: string;
|
|
109
|
+
isDark?: boolean;
|
|
110
|
+
className?: string;
|
|
111
|
+
/** When true, the iframe height auto-adapts to its content. Set via `_meta.ui.autoHeight` in the tool result. */
|
|
112
|
+
autoHeight?: boolean;
|
|
113
|
+
/** Called when the view requests to open a URL */
|
|
114
|
+
onOpenLink?: (url: string) => void;
|
|
115
|
+
/** Called when the view sends a chat message */
|
|
116
|
+
onMessage?: (message: {
|
|
117
|
+
role: string;
|
|
118
|
+
content: string;
|
|
119
|
+
}) => void;
|
|
52
120
|
}
|
|
121
|
+
declare function McpAppFrame({ resourceUri, toolInput, toolResult, resourceEndpoint, isDark, className, autoHeight, onOpenLink, onMessage, }: McpAppFrameProps): react_jsx_runtime.JSX.Element;
|
|
53
122
|
|
|
54
|
-
declare
|
|
123
|
+
declare const ChatCard: react.ForwardRefExoticComponent<ChatCardProps & react.RefAttributes<ChatHandle>>;
|
|
55
124
|
|
|
56
125
|
declare const DEFAULT_THEME: Required<ChatTheme>;
|
|
126
|
+
declare const DARK_THEME: ChatTheme;
|
|
57
127
|
declare function mergeTheme(userTheme?: ChatTheme): Required<ChatTheme>;
|
|
58
128
|
declare function themeToCSSProperties(theme: Required<ChatTheme>): Record<string, string>;
|
|
59
129
|
|
|
60
|
-
export { type ChatTheme, ChatWidget, type ChatWidgetProps, DEFAULT_THEME, mergeTheme, themeToCSSProperties };
|
|
130
|
+
export { ChatBar, type ChatBarProps, type ChatBaseProps, ChatCard, type ChatCardProps, type ChatHandle, type ChatTheme, ChatBar as ChatWidget, type ChatWidgetProps, DARK_THEME, DEFAULT_THEME, McpAppFrame, type McpAppFrameProps, type SuggestionsConfig, mergeTheme, themeToCSSProperties };
|
package/dist/chat/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{useChat as ut}from"@ai-sdk/react";import{DefaultChatTransport as ct}from"ai";import{useCallback as Z,useEffect as dt,useRef as we,useState as Ie}from"react";import{FileIcon as Re}from"lucide-react";import{clsx as He}from"clsx";import{twMerge as Ae}from"tailwind-merge";function s(...e){return Ae(He(e))}import{jsx as U,jsxs as Be}from"react/jsx-runtime";var ee=({files:e,className:t,...o})=>e.length===0?null:U("div",{className:s("flex flex-wrap gap-1.5",t),...o,children:e.map((r,n)=>U(Fe,{file:r},n))});function Fe({file:e}){return e.mediaType?.startsWith("image/")&&e.url?U("img",{src:e.url,alt:e.filename??"attachment",className:"h-16 max-w-32 rounded object-cover"}):Be("span",{className:"inline-flex items-center gap-1.5 rounded bg-background/20 px-2 py-1 text-xs",children:[U(Re,{className:"size-3 shrink-0"}),U("span",{className:"max-w-24 truncate",children:e.filename??"file"})]})}import{ArrowDownIcon as De}from"lucide-react";import{useCallback as Ue}from"react";import{StickToBottom as te,useStickToBottomContext as ze}from"use-stick-to-bottom";import{jsx as Se}from"react/jsx-runtime";var B=({className:e,variant:t="default",size:o="default",type:r="button",...n})=>Se("button",{type:r,className:s("inline-flex cursor-pointer items-center justify-center rounded-md font-medium transition-colors disabled:pointer-events-none disabled:opacity-50",t==="default"&&"bg-primary text-primary-foreground hover:bg-primary/90",t==="outline"&&"border border-border bg-background hover:bg-accent hover:text-accent-foreground",t==="ghost"&&"hover:bg-accent hover:text-accent-foreground",o==="default"&&"h-9 px-4 py-2 text-sm",o==="sm"&&"h-8 px-3 text-xs",o==="icon"&&"size-9",o==="icon-sm"&&"size-7",e),...n});import{jsx as q}from"react/jsx-runtime";var oe=({className:e,...t})=>q(te,{className:s("relative flex-1 overflow-y-hidden",e),initial:"smooth",resize:"smooth",role:"log",...t}),re=({className:e,...t})=>q(te.Content,{className:s("flex flex-col gap-8 p-4",e),...t}),ne=({className:e,...t})=>{let{isAtBottom:o,scrollToBottom:r}=ze(),n=Ue(()=>{r()},[r]);return!o&&q(B,{className:s("absolute bottom-4 left-[50%] translate-x-[-50%] rounded-full",e),onClick:n,size:"icon",variant:"outline",...t,children:q(De,{className:"size-4"})})};import{jsx as se}from"react/jsx-runtime";var K=({className:e,size:t=5,...o})=>se("div",{className:s("flex items-center gap-1",e),...o,children:[0,1,2].map(r=>se("div",{className:"rounded-full bg-muted-foreground/60",style:{width:t,height:t,animation:"ww-pulse 1.4s ease-in-out infinite",animationDelay:`${r*.2}s`}},r))});import{cjk as Oe}from"@streamdown/cjk";import{code as We}from"@streamdown/code";import{memo as qe}from"react";import{Streamdown as Ve}from"streamdown";import{jsx as $}from"react/jsx-runtime";var V=({className:e,from:t,...o})=>$("div",{className:s("group flex w-full max-w-[95%] flex-col gap-2",t==="user"?"is-user ml-auto justify-end":"is-assistant",e),...o}),j=({children:e,className:t,...o})=>$("div",{className:s("flex w-fit min-w-0 max-w-full flex-col gap-2 overflow-hidden text-sm","group-[.is-user]:ml-auto group-[.is-user]:rounded-lg group-[.is-user]:bg-primary group-[.is-user]:px-4 group-[.is-user]:py-3 group-[.is-user]:text-primary-foreground","group-[.is-assistant]:rounded-lg group-[.is-assistant]:bg-accent group-[.is-assistant]:px-4 group-[.is-assistant]:py-3 group-[.is-assistant]:text-foreground",t),...o,children:e}),je={cjk:Oe,code:We},_=qe(({className:e,...t})=>$(Ve,{className:s("size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0",e),plugins:je,...t}),(e,t)=>e.children===t.children);_.displayName="MessageResponse";import{ArrowUpIcon as _e,LoaderIcon as Ke,PaperclipIcon as $e,SquareIcon as Je,XIcon as Xe}from"lucide-react";import{nanoid as Ge}from"nanoid";import{createContext as Qe,useCallback as M,useContext as Ye,useEffect as J,useMemo as Ze,useRef as X,useState as ae}from"react";import{jsx as h,jsxs as de}from"react/jsx-runtime";var et=async e=>{try{let o=await(await fetch(e)).blob();return new Promise(r=>{let n=new FileReader;n.onloadend=()=>r(n.result),n.onerror=()=>r(null),n.readAsDataURL(o)})}catch{return null}},ie=Qe(null),le=()=>{let e=Ye(ie);if(!e)throw new Error("usePromptInputAttachments must be used within a PromptInput");return e},pe=({className:e,accept:t,multiple:o,globalDrop:r,maxFiles:n,maxFileSize:l,onSubmit:g,children:b,...w})=>{let v=X(null),d=X(null),[c,y]=ae([]),H=X(c);J(()=>{H.current=c},[c]);let P=M(()=>{v.current?.click()},[]),I=M(a=>{let x=[...a];if(x.length===0)return;let f=L=>l?L.size<=l:!0,C=x.filter(f);y(L=>{let N=typeof n=="number"?Math.max(0,n-L.length):void 0,T=typeof N=="number"?C.slice(0,N):C;return[...L,...T.map(k=>({filename:k.name,id:Ge(),mediaType:k.type,type:"file",url:URL.createObjectURL(k)}))]})},[n,l]),A=M(a=>{y(x=>{let f=x.find(C=>C.id===a);return f?.url&&URL.revokeObjectURL(f.url),x.filter(C=>C.id!==a)})},[]),R=M(()=>{y(a=>{for(let x of a)x.url&&URL.revokeObjectURL(x.url);return[]})},[]);J(()=>()=>{for(let a of H.current)a.url&&URL.revokeObjectURL(a.url)},[]);let z=M(a=>{a.currentTarget.files&&I(a.currentTarget.files),a.currentTarget.value=""},[I]);J(()=>{if(!r)return;let a=f=>{f.dataTransfer?.types?.includes("Files")&&f.preventDefault()},x=f=>{f.dataTransfer?.types?.includes("Files")&&f.preventDefault(),f.dataTransfer?.files&&f.dataTransfer.files.length>0&&I(f.dataTransfer.files)};return document.addEventListener("dragover",a),document.addEventListener("drop",x),()=>{document.removeEventListener("dragover",a),document.removeEventListener("drop",x)}},[I,r]);let D=M(async a=>{a.preventDefault();let x=a.currentTarget,C=new FormData(x).get("message")||"";x.reset();let L=await Promise.all(c.map(async({id:N,...T})=>{if(T.url?.startsWith("blob:")){let k=await et(T.url);return{...T,url:k??T.url}}return T}));try{let N=g({files:L,text:C},a);N instanceof Promise&&await N,R()}catch{}},[c,g,R]),O=Ze(()=>({add:I,clear:R,files:c,openFileDialog:P,remove:A}),[c,I,A,R,P]);return de(ie.Provider,{value:O,children:[h("input",{accept:t,"aria-label":"Upload files",className:"hidden",multiple:o,onChange:z,ref:v,title:"Upload files",type:"file"}),h("form",{className:s("flex w-full flex-col rounded-lg border border-border bg-background",e),onSubmit:D,ref:d,...w,children:b})]})};var me=({onChange:e,onKeyDown:t,className:o,placeholder:r="What would you like to know?",...n})=>{let l=le(),[g,b]=ae(!1),w=M(d=>{if(t?.(d),!d.defaultPrevented){if(d.key==="Enter"){if(g||d.nativeEvent.isComposing||d.shiftKey)return;d.preventDefault();let{form:c}=d.currentTarget;if(c?.querySelector('button[type="submit"]')?.disabled)return;c?.requestSubmit()}if(d.key==="Backspace"&&d.currentTarget.value===""&&l.files.length>0){d.preventDefault();let c=l.files.at(-1);c&&l.remove(c.id)}}},[t,g,l]),v=M(d=>{let c=d.clipboardData?.items;if(!c)return;let y=[];for(let H of c)if(H.kind==="file"){let P=H.getAsFile();P&&y.push(P)}y.length>0&&(d.preventDefault(),l.add(y))},[l]);return h("textarea",{className:s("field-sizing-content max-h-48 min-h-16 w-full resize-none border-0 bg-transparent px-3 py-3 text-sm outline-none placeholder:text-muted-foreground",o),name:"message",onCompositionEnd:()=>b(!1),onCompositionStart:()=>b(!0),onKeyDown:w,onPaste:v,placeholder:r,onChange:e,...n})},ue=({className:e,status:t,onStop:o,onClick:r,children:n,...l})=>{let g=t==="submitted"||t==="streaming",b=h(_e,{className:"size-4"});t==="submitted"?b=h(Ke,{className:"size-4 animate-spin"}):t==="streaming"&&(b=h(Je,{className:"size-4"}));let w=M(v=>{if(g&&o){v.preventDefault(),o();return}r?.(v)},[g,o,r]);return h(B,{"aria-label":g?"Stop":"Submit",className:s(e),onClick:w,size:"icon-sm",type:g&&o?"button":"submit",variant:"default",...l,children:n??b})},ce=({className:e,children:t,...o})=>{let r=le();return r.files.length>0?de(B,{className:s("group relative",e),onClick:()=>r.clear(),size:"icon-sm",type:"button",variant:"ghost","aria-label":"Remove all attachments",...o,children:[h("span",{className:"flex size-5 items-center justify-center rounded-full bg-primary text-[10px] font-medium text-primary-foreground transition-opacity group-hover:opacity-0",children:r.files.length}),h(Xe,{className:"absolute size-4 opacity-0 transition-opacity group-hover:opacity-100"})]}):h(B,{className:s(e),onClick:()=>r.openFileDialog(),size:"icon-sm",type:"button",variant:"ghost",...o,children:t??h($e,{className:"size-4"})})};import{CheckCircleIcon as fe,ChevronDownIcon as tt,CircleIcon as ot,ClockIcon as ge,WrenchIcon as rt,XCircleIcon as xe}from"lucide-react";import{createContext as nt,isValidElement as st,useContext as be,useState as at}from"react";import{jsx as i,jsxs as S}from"react/jsx-runtime";var G=nt({open:!1,toggle:()=>{}}),he=({className:e,defaultOpen:t=!1,children:o,...r})=>{let[n,l]=at(t);return i(G.Provider,{value:{open:n,toggle:()=>l(g=>!g)},children:i("div",{className:s("mb-4 w-full rounded-md border border-border",e),"data-state":n?"open":"closed",...r,children:o})})},it={"approval-requested":"Awaiting Approval","approval-responded":"Responded","input-available":"Running","input-streaming":"Pending","output-available":"Completed","output-denied":"Denied","output-error":"Error"},lt={"approval-requested":i(ge,{className:"size-4 text-yellow-600"}),"approval-responded":i(fe,{className:"size-4 text-blue-600"}),"input-available":i(ge,{className:"size-4 animate-pulse"}),"input-streaming":i(ot,{className:"size-4"}),"output-available":i(fe,{className:"size-4 text-green-600"}),"output-denied":i(xe,{className:"size-4 text-orange-600"}),"output-error":i(xe,{className:"size-4 text-red-600"})},pt=e=>S("span",{className:"inline-flex items-center gap-1.5 rounded-full border border-border bg-muted px-2 py-0.5 text-xs text-muted-foreground",children:[lt[e],it[e]]}),ve=({className:e,title:t,state:o,...r})=>{let{open:n,toggle:l}=be(G);return S("button",{type:"button",onClick:l,className:s("flex w-full items-center justify-between gap-4 p-3",e),"aria-expanded":n,...r,children:[S("div",{className:"flex items-center gap-2",children:[i(rt,{className:"size-4 text-muted-foreground"}),i("span",{className:"text-sm font-medium",children:t}),pt(o)]}),i(tt,{className:s("size-4 text-muted-foreground transition-transform",n&&"rotate-180")})]})},ye=({className:e,children:t,...o})=>{let{open:r}=be(G);return r?i("div",{className:s("space-y-4 p-4",e),...o,children:t}):null},Pe=({className:e,input:t,...o})=>S("div",{className:s("space-y-2 overflow-hidden",e),...o,children:[i("h4",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:"Parameters"}),i("pre",{className:"overflow-x-auto rounded-md bg-muted/50 p-3 text-xs",children:i("code",{children:JSON.stringify(t,null,2)})})]}),Ce=({className:e,output:t,errorText:o,...r})=>{if(!(t||o))return null;let n;return typeof t=="object"&&!st(t)?n=i("pre",{className:"overflow-x-auto p-3 text-xs",children:i("code",{children:JSON.stringify(t,null,2)})}):typeof t=="string"?n=i("pre",{className:"overflow-x-auto p-3 text-xs",children:i("code",{children:t})}):n=i("div",{className:"p-3",children:t}),S("div",{className:s("space-y-2",e),...r,children:[i("h4",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:o?"Error":"Result"}),S("div",{className:s("overflow-x-auto rounded-md text-xs",o?"bg-destructive/10 text-destructive":"bg-muted/50 text-foreground"),children:[o&&i("div",{className:"p-3",children:o}),n]})]})};var Te={primaryColor:"#6366f1",primaryForeground:"#ffffff",backgroundColor:"#ffffff",textColor:"#1f2937",mutedColor:"#6b7280",borderColor:"#e5e7eb",assistantBubbleColor:"#f3f4f6",userBubbleColor:"#6366f1",inputBackgroundColor:"#f9fafb",borderRadius:16,messageBorderRadius:12,fontFamily:"system-ui, -apple-system, 'Segoe UI', sans-serif"},mt={primaryColor:["--ww-primary","--color-primary"],primaryForeground:["--ww-primary-fg","--color-primary-foreground"],backgroundColor:["--ww-bg","--color-background"],textColor:["--ww-text","--color-foreground","--color-accent-foreground"],mutedColor:["--ww-muted","--color-muted-foreground"],borderColor:["--ww-border","--color-border"],assistantBubbleColor:["--ww-assistant-bubble","--color-accent"],userBubbleColor:["--ww-user-bubble"],inputBackgroundColor:["--ww-input-bg","--color-input"],borderRadius:["--ww-radius","--radius"],messageBorderRadius:["--ww-msg-radius"],fontFamily:["--ww-font"]};function Q(e){return{...Te,...e}}function Y(e){let t={};for(let[o,r]of Object.entries(mt)){let n=e[o],l=typeof n=="number"?`${n}px`:String(n);for(let g of r)t[g]=l}return t}import{jsx as u,jsxs as E}from"react/jsx-runtime";function ft(e){let{api:t="https://app.waniwani.ai/api/chat",welcomeMessage:o,theme:r,headers:n,body:l,width:g=600,expandedHeight:b=400,allowAttachments:w=!1,onMessageSent:v,onResponseReceived:d}=e,c=Q(r),y=Y(c),H=we(new ct({api:t,headers:{...n},body:l})),{messages:P,sendMessage:I,status:A}=ut({transport:H.current,onFinish(){d?.()}}),[R,z]=Ie(""),[D,O]=Ie(!1),a=we(null),x=P.length>0,f=D;dt(()=>{if(!D)return;let m=F=>{a.current&&!a.current.contains(F.target)&&O(!1)};return document.addEventListener("mousedown",m),()=>document.removeEventListener("mousedown",m)},[D]);let C=Z(m=>{let F=!!m.text?.trim(),W=!!m.files?.length;(F||W)&&(I({text:m.text||"",files:m.files}),v?.(m.text||""),z(""))},[I,v]),L=Z(m=>{z(m.target.value)},[]),N=Z(()=>{O(!0)},[]),T=A==="submitted"||A==="streaming",k=P[P.length-1],Me=T&&(!x||k.role==="user");return E("div",{ref:a,style:{...y,width:g},"data-waniwani-chat":"",className:"flex flex-col font-[family-name:var(--ww-font)] text-foreground",children:[u("div",{className:s("overflow-hidden bg-background/80 backdrop-blur-xl transition-all duration-300 ease-out",f?"opacity-100 translate-y-0":"opacity-0 translate-y-2 pointer-events-none max-h-0"),style:{...f?{maxHeight:b}:void 0,maskImage:"linear-gradient(to bottom, transparent, black 24px, black calc(100% - 16px), transparent), linear-gradient(to right, transparent, black 16px, black calc(100% - 16px), transparent)",maskComposite:"intersect",WebkitMaskImage:"linear-gradient(to bottom, transparent, black 24px, black calc(100% - 16px), transparent), linear-gradient(to right, transparent, black 16px, black calc(100% - 16px), transparent)",WebkitMaskComposite:"source-in"},children:E(oe,{className:"flex-1",style:{height:b},children:[E(re,{children:[o&&u(V,{from:"assistant",children:u(j,{children:u(_,{children:o})})}),P.map(m=>{let F=m.parts.filter(p=>p.type==="text"),W=m.parts.filter(p=>p.type==="file"),Le=m.parts.filter(p=>"toolCallId"in p),Ne=m===k&&m.role==="assistant",ke=F.length>0;return E(V,{from:m.role,children:[Le.map(p=>E(he,{defaultOpen:p.state==="output-available",children:[u(ve,{title:p.title??p.type.replace("tool-",""),state:p.state}),E(ye,{children:[u(Pe,{input:p.input}),"output"in p&&p.output!==void 0&&u(Ce,{output:p.output,errorText:"errorText"in p?p.errorText:void 0})]})]},p.toolCallId)),E(j,{children:[W.length>0&&u(ee,{files:W}),ke?F.map((p,Ee)=>u(_,{children:p.type==="text"?p.text:""},`${m.id}-${Ee}`)):Ne&&T&&u(K,{})]})]},m.id)}),Me&&u(V,{from:"assistant",children:u(j,{children:u(K,{})})})]}),u(ne,{})]})}),u("div",{className:"shrink-0",children:u(pe,{onSubmit:C,globalDrop:w,multiple:w,className:s("rounded-[var(--ww-radius)] shadow-sm transition-all duration-300 ease-out"),children:E("div",{className:"flex items-center gap-1 px-3 py-2",children:[w&&u(ce,{}),u(me,{onChange:L,value:R,placeholder:"Type a message...",onFocus:N,className:"min-h-0 py-1.5 px-2"}),u(ue,{status:A})]})})})]})}export{ft as ChatWidget,Te as DEFAULT_THEME,Q as mergeTheme,Y as themeToCSSProperties};
|
|
2
|
+
import{forwardRef as no,useCallback as et,useEffect as so,useImperativeHandle as ao,useRef as io,useState as lo}from"react";import{ArrowDownIcon as nt}from"lucide-react";import{useCallback as st}from"react";import{StickToBottom as Ie,useStickToBottomContext as at}from"use-stick-to-bottom";import{clsx as tt}from"clsx";import{twMerge as ot}from"tailwind-merge";function u(...t){return ot(tt(t))}import{jsx as rt}from"react/jsx-runtime";var z=({className:t,variant:e="default",size:o="default",type:n="button",...r})=>rt("button",{type:n,className:u("inline-flex cursor-pointer items-center justify-center rounded-md font-medium transition-colors disabled:pointer-events-none disabled:opacity-50",e==="default"&&"bg-primary text-primary-foreground hover:bg-primary/90",e==="outline"&&"border border-border bg-background hover:bg-accent hover:text-accent-foreground",e==="ghost"&&"hover:bg-accent hover:text-accent-foreground",o==="default"&&"h-9 px-4 py-2 text-sm",o==="sm"&&"h-8 px-3 text-xs",o==="icon"&&"size-9",o==="icon-sm"&&"size-7",t),...r});import{jsx as X}from"react/jsx-runtime";var Z=({className:t,...e})=>X(Ie,{className:u("relative flex-1 overflow-y-hidden",t),initial:"smooth",resize:"smooth",role:"log",...e}),Q=({className:t,...e})=>X(Ie.Content,{className:u("flex flex-col gap-8 p-4",t),...e}),Y=({className:t,...e})=>{let{isAtBottom:o,scrollToBottom:n}=at(),r=st(()=>{n()},[n]);return!o&&X(z,{className:u("absolute bottom-4 left-[50%] translate-x-[-50%] rounded-full",t),onClick:r,size:"icon",variant:"outline",...e,children:X(nt,{className:"size-4"})})};import{ArrowUpIcon as it,LoaderIcon as lt,PaperclipIcon as ut,SquareIcon as ct,XIcon as pt}from"lucide-react";import{nanoid as mt}from"nanoid";import{createContext as dt,useCallback as U,useContext as ft,useEffect as ge,useMemo as gt,useRef as he,useState as Ee}from"react";import{jsx as A,jsxs as Re}from"react/jsx-runtime";var ht=async t=>{try{let o=await(await fetch(t)).blob();return new Promise(n=>{let r=new FileReader;r.onloadend=()=>n(r.result),r.onerror=()=>n(null),r.readAsDataURL(o)})}catch{return null}},Ne=dt(null),Le=()=>{let t=ft(Ne);if(!t)throw new Error("usePromptInputAttachments must be used within a PromptInput");return t},ee=({className:t,accept:e,multiple:o,globalDrop:n,maxFiles:r,maxFileSize:s,onSubmit:a,children:p,...C})=>{let i=he(null),g=he(null),[m,v]=Ee([]),w=he(m);ge(()=>{w.current=m},[m]);let d=U(()=>{i.current?.click()},[]),T=U(b=>{let f=[...b];if(f.length===0)return;let x=S=>s?S.size<=s:!0,R=f.filter(x);v(S=>{let D=typeof r=="number"?Math.max(0,r-S.length):void 0,E=typeof D=="number"?R.slice(0,D):R;return[...S,...E.map(k=>({filename:k.name,id:mt(),mediaType:k.type,type:"file",url:URL.createObjectURL(k)}))]})},[r,s]),c=U(b=>{v(f=>{let x=f.find(R=>R.id===b);return x?.url&&URL.revokeObjectURL(x.url),f.filter(R=>R.id!==b)})},[]),l=U(()=>{v(b=>{for(let f of b)f.url&&URL.revokeObjectURL(f.url);return[]})},[]);ge(()=>()=>{for(let b of w.current)b.url&&URL.revokeObjectURL(b.url)},[]);let h=U(b=>{b.currentTarget.files&&T(b.currentTarget.files),b.currentTarget.value=""},[T]);ge(()=>{if(!n)return;let b=x=>{x.dataTransfer?.types?.includes("Files")&&x.preventDefault()},f=x=>{x.dataTransfer?.types?.includes("Files")&&x.preventDefault(),x.dataTransfer?.files&&x.dataTransfer.files.length>0&&T(x.dataTransfer.files)};return document.addEventListener("dragover",b),document.addEventListener("drop",f),()=>{document.removeEventListener("dragover",b),document.removeEventListener("drop",f)}},[T,n]);let P=U(async b=>{b.preventDefault();let f=b.currentTarget,R=new FormData(f).get("message")||"";f.reset();let S=await Promise.all(m.map(async({id:D,...E})=>{if(E.url?.startsWith("blob:")){let k=await ht(E.url);return{...E,url:k??E.url}}return E}));try{let D=a({files:S,text:R},b);D instanceof Promise&&await D,l()}catch{}},[m,a,l]),M=gt(()=>({add:T,clear:l,files:m,openFileDialog:d,remove:c}),[m,T,c,l,d]);return Re(Ne.Provider,{value:M,children:[A("input",{accept:e,"aria-label":"Upload files",className:"hidden",multiple:o,onChange:h,ref:i,title:"Upload files",type:"file"}),A("form",{className:u("flex w-full flex-col rounded-lg border border-border bg-background",t),onSubmit:P,ref:g,...C,children:p})]})};var te=({onChange:t,onKeyDown:e,className:o,placeholder:n="What would you like to know?",...r})=>{let s=Le(),[a,p]=Ee(!1),C=U(g=>{if(e?.(g),!g.defaultPrevented){if(g.key==="Enter"){if(a||g.nativeEvent.isComposing||g.shiftKey)return;g.preventDefault();let{form:m}=g.currentTarget;if(m?.querySelector('button[type="submit"]')?.disabled)return;m?.requestSubmit()}if(g.key==="Backspace"&&g.currentTarget.value===""&&s.files.length>0){g.preventDefault();let m=s.files.at(-1);m&&s.remove(m.id)}}},[e,a,s]),i=U(g=>{let m=g.clipboardData?.items;if(!m)return;let v=[];for(let w of m)if(w.kind==="file"){let d=w.getAsFile();d&&v.push(d)}v.length>0&&(g.preventDefault(),s.add(v))},[s]);return A("textarea",{className:u("field-sizing-content max-h-48 min-h-16 w-full resize-none border-0 bg-transparent px-3 py-3 text-sm outline-none placeholder:text-muted-foreground",o),name:"message",onCompositionEnd:()=>p(!1),onCompositionStart:()=>p(!0),onKeyDown:C,onPaste:i,placeholder:n,onChange:t,...r})},oe=({className:t,status:e,onStop:o,onClick:n,children:r,...s})=>{let a=e==="submitted"||e==="streaming",p=A(it,{className:"size-4"});e==="submitted"?p=A(lt,{className:"size-4 animate-spin"}):e==="streaming"&&(p=A(ct,{className:"size-4"}));let C=U(i=>{if(a&&o){i.preventDefault(),o();return}n?.(i)},[a,o,n]);return A(z,{"aria-label":a?"Stop":"Submit",className:u("bg-foreground text-background hover:bg-foreground",t),onClick:C,size:"icon-sm",type:a&&o?"button":"submit",variant:"ghost",...s,children:r??p})},re=({className:t,children:e,...o})=>{let n=Le();return n.files.length>0?Re(z,{className:u("group relative",t),onClick:()=>n.clear(),size:"icon-sm",type:"button",variant:"ghost","aria-label":"Remove all attachments",...o,children:[A("span",{className:"flex size-5 items-center justify-center rounded-full bg-primary text-[10px] font-medium text-primary-foreground transition-opacity group-hover:opacity-0",children:n.files.length}),A(pt,{className:"absolute size-4 opacity-0 transition-opacity group-hover:opacity-100"})]}):A(z,{className:u(t),onClick:()=>n.openFileDialog(),size:"icon-sm",type:"button",variant:"ghost",...o,children:e??A(ut,{className:"size-4"})})};import{FileIcon as bt}from"lucide-react";import{jsx as K,jsxs as Ct}from"react/jsx-runtime";var Ae=({files:t,className:e,...o})=>t.length===0?null:K("div",{className:u("flex flex-wrap gap-1.5",e),...o,children:t.map((n,r)=>K(xt,{file:n},r))});function xt({file:t}){return t.mediaType?.startsWith("image/")&&t.url?K("img",{src:t.url,alt:t.filename??"attachment",className:"h-16 max-w-32 rounded object-cover"}):Ct("span",{className:"inline-flex items-center gap-1.5 rounded bg-background/20 px-2 py-1 text-xs",children:[K(bt,{className:"size-3 shrink-0"}),K("span",{className:"max-w-24 truncate",children:t.filename??"file"})]})}import{jsx as He}from"react/jsx-runtime";var be=({className:t,size:e=5,...o})=>He("div",{className:u("flex items-center gap-1",t),...o,children:[0,1,2].map(n=>He("div",{className:"rounded-full bg-muted-foreground/60",style:{width:e,height:e,animation:"ww-pulse 1.4s ease-in-out infinite",animationDelay:`${n*.2}s`}},n))});import{cjk as yt}from"@streamdown/cjk";import{code as vt}from"@streamdown/code";import{memo as wt}from"react";import{Streamdown as Tt}from"streamdown";import{jsx as xe}from"react/jsx-runtime";var ne=({className:t,from:e,...o})=>xe("div",{className:u("group flex w-full max-w-[95%] flex-col gap-2",e==="user"?"is-user ml-auto justify-end":"is-assistant",t),...o}),se=({children:t,className:e,...o})=>xe("div",{className:u("flex w-fit min-w-0 max-w-full flex-col gap-2 overflow-hidden text-base","group-[.is-user]:ml-auto group-[.is-user]:rounded-lg group-[.is-user]:bg-user-bubble group-[.is-user]:px-4 group-[.is-user]:py-3 group-[.is-user]:text-primary-foreground","group-[.is-assistant]:text-foreground",e),...o,children:t}),Pt={cjk:yt,code:vt},ae=wt(({className:t,...e})=>xe(Tt,{className:u("size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0",t),plugins:Pt,...e}),(t,e)=>t.children===e.children);ae.displayName="MessageResponse";import{jsx as Mt}from"react/jsx-runtime";function Be({className:t,text:e,...o}){return e?Mt("pre",{className:u("mb-2 overflow-x-auto whitespace-pre-wrap break-words text-xs font-mono text-muted-foreground",t),...o,children:e}):null}import{BracesIcon as kt,CheckIcon as St,ChevronDownIcon as It,ChevronRightIcon as Et,ClipboardCopyIcon as Nt,ServerIcon as Qo}from"lucide-react";import{createContext as Lt,useCallback as Rt,useContext as Fe,useEffect as At,useMemo as Ht,useRef as Bt,useState as Ce}from"react";import{Fragment as De,jsx as y,jsxs as W}from"react/jsx-runtime";function Dt(t,e=80){if(t==null)return String(t);if(typeof t!="object")return String(t).slice(0,e);if(Array.isArray(t))return`Array(${t.length})`;let o=JSON.stringify(t);if(o.length<=e)return o;let n=Object.entries(t),r=[],s=e-2;for(let[a,p]of n){if(s<=8)break;let C=a.length>4?`${a.slice(0,4)}\u2026`:a,i;typeof p=="string"?i=p.length>2?`'${p.slice(0,1)}\u2026`:`'${p}'`:Array.isArray(p)?i=`Array(${p.length})`:typeof p=="object"&&p!==null?i="{\u2026}":i=String(p);let g=`${C}\u2009${i}`;r.push(g),s-=g.length+3}return`{${r.join(", ")}}`}function Ft({text:t,className:e}){let[o,n]=Ce(!1),r=Bt(null);At(()=>()=>{r.current&&clearTimeout(r.current)},[]);let s=Rt(async a=>{a.stopPropagation();try{await navigator.clipboard.writeText(t),n(!0),r.current&&clearTimeout(r.current),r.current=setTimeout(()=>n(!1),2e3)}catch{}},[t]);return y(z,{variant:"ghost",size:"sm",onClick:s,className:u("h-auto gap-1 px-1.5 py-0.5 text-xs text-muted-foreground hover:text-foreground",e),children:o?W(De,{children:[y(St,{className:"size-3.5"}),y("span",{children:"Copied"})]}):W(De,{children:[y(Nt,{className:"size-3.5"}),y("span",{children:"Copy"})]})})}function Ue({data:t,label:e,className:o,...n}){let[r,s]=Ce(!1),a=Ht(()=>JSON.stringify(t,null,2),[t]),p=Dt(t);return W("div",{className:u("rounded-lg bg-tool-card",o),...n,children:[W("div",{className:"flex items-center justify-between px-3 pt-2.5 pb-1.5",children:[y("span",{className:"text-xs font-medium text-muted-foreground",children:e}),y(Ft,{text:a})]}),W("button",{type:"button",onClick:()=>s(C=>!C),className:"flex w-full items-start gap-2 px-3 pb-3 text-left",children:[y(Et,{className:u("mt-0.5 size-3.5 shrink-0 text-muted-foreground transition-transform duration-150",r&&"rotate-90")}),r?y("pre",{className:"overflow-x-auto text-xs font-mono text-foreground whitespace-pre-wrap break-all",children:y("code",{children:a})}):y("span",{className:"truncate text-xs font-mono text-foreground/80",children:p})]})]})}var ye=Lt({open:!1,toggle:()=>{}});function Oe({className:t,defaultOpen:e=!1,children:o,...n}){let[r,s]=Ce(e);return y(ye.Provider,{value:{open:r,toggle:()=>s(a=>!a)},children:y("div",{className:u("mb-4 w-full",t),"data-state":r?"open":"closed",...n,children:o})})}function ze({className:t,title:e,state:o,...n}){let{open:r,toggle:s}=Fe(ye),a=o==="input-available"||o==="input-streaming";return W("button",{type:"button",onClick:s,className:u("flex w-full items-center justify-between gap-3 py-1.5",t),"aria-expanded":r,...n,children:[W("div",{className:"flex min-w-0 items-center gap-2",children:[y(kt,{className:"size-4 shrink-0 text-muted-foreground"}),y("span",{className:"truncate text-sm font-medium",children:e}),a&&y("span",{className:"size-2 shrink-0 rounded-full bg-primary animate-pulse"})]}),y(It,{className:u("size-4 shrink-0 text-muted-foreground transition-transform duration-200",r&&"rotate-180")})]})}function We({className:t,children:e,...o}){let{open:n}=Fe(ye);return y("div",{className:u("grid transition-[grid-template-rows,opacity] duration-200 ease-out",n?"grid-rows-[1fr] opacity-100":"grid-rows-[0fr] opacity-0"),children:y("div",{className:"min-h-0 overflow-hidden",children:y("div",{className:u("mt-2 space-y-3 rounded-lg border border-border bg-background p-3",t),...o,children:e})})})}function $e({className:t,input:e,...o}){return y(Ue,{data:e,label:"Request",className:t,...o})}function je(t){if(typeof t!="object"||t===null)return;let e=t._meta;if(typeof e!="object"||e===null)return;let o=e.ui;if(!(typeof o!="object"||o===null))return o}function _e(t){let e=je(t)?.resourceUri;return typeof e=="string"?e:void 0}function Ke(t){return je(t)?.autoHeight===!0}function Ve({className:t,output:e,errorText:o,...n}){return e||o?o?W("div",{className:u("space-y-2",t),...n,children:[y("h4",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:"Error"}),y("div",{className:"rounded-lg bg-destructive/10 p-3 text-xs text-destructive",children:o})]}):y(Ue,{data:e,label:"Response",className:t,...n}):null}import{useCallback as Ut,useEffect as qe,useMemo as Ot,useRef as $,useState as Je}from"react";import{jsx as Kt}from"react/jsx-runtime";var zt="/api/mcp/resource",Wt=500,$t=300,jt="2026-01-26",_t=300;function ve({resourceUri:t,toolInput:e,toolResult:o,resourceEndpoint:n=zt,isDark:r=!1,className:s,autoHeight:a=!0,onOpenLink:p,onMessage:C}){let i=$(null),g=$(e),m=$(o),v=$({width:0,height:0}),w=$(!1),[d,T]=Je($t),[c,l]=Je(void 0),h=$(p),P=$(C);g.current=e,m.current=o,h.current=p,P.current=C;let M=Ut(x=>a?Math.max(x,0):Math.min(Math.max(x,50),Wt),[a]),b=Ot(()=>`${n}?uri=${encodeURIComponent(t)}`,[n,t]),f=$(r);return f.current=r,qe(()=>{if(!w.current)return;let x=i.current;x?.contentWindow&&x.contentWindow.postMessage({jsonrpc:"2.0",method:"ui/notifications/host-context-changed",params:{theme:r?"dark":"light"}},"*")},[r]),qe(()=>{let x=i.current;if(!x)return;let R=!1,S=E=>{x.contentWindow?.postMessage(E,"*")},D=E=>{if(R||E.source!==x.contentWindow)return;let k=E.data;if(!k||typeof k!="object"||k.jsonrpc!=="2.0")return;let O=k.method,N=k.id;if(O==="ui/initialize"&&N!=null){S({jsonrpc:"2.0",id:N,result:{protocolVersion:k.params?.protocolVersion??jt,hostInfo:{name:"WaniWani Chat",version:"1.0.0"},hostCapabilities:{openLinks:{},message:{}},hostContext:{theme:f.current?"dark":"light",displayMode:"inline"}}});return}if(O==="ui/notifications/initialized"){w.current=!0;let H=g.current,F=m.current;S({jsonrpc:"2.0",method:"ui/notifications/tool-input",params:{arguments:H}});let j=F.content??[{type:"text",text:JSON.stringify(F)}];S({jsonrpc:"2.0",method:"ui/notifications/tool-result",params:{content:j,structuredContent:F.structuredContent}});return}if(O==="ui/notifications/size-changed"){let H=k.params,F=typeof H?.height=="number"?H.height:void 0,j=typeof H?.width=="number"?H.width:void 0,G=v.current,Me=F!==void 0&&F!==G.height,ke=j!==void 0&&j!==G.width;if(!Me&&!ke)return;if(Me&&F!==void 0){G.height=F;let fe=M(F);if(x.animate){let Se=x.getBoundingClientRect().height;Math.abs(Se-fe)>2&&x.animate([{height:`${Se}px`},{height:`${fe}px`}],{duration:_t,easing:"ease-out",fill:"forwards"})}T(fe)}ke&&a&&j!==void 0&&(G.width=j,l(j));return}if(O==="ui/open-link"&&N!=null){let H=k.params?.url;typeof H=="string"&&(h.current?h.current(H):window.open(H,"_blank","noopener,noreferrer")),S({jsonrpc:"2.0",id:N,result:{}});return}if(O==="ui/message"&&N!=null){P.current&&k.params&&P.current(k.params),S({jsonrpc:"2.0",id:N,result:{}});return}if(O==="ui/request-display-mode"&&N!=null){S({jsonrpc:"2.0",id:N,result:{}});return}if(O==="ui/resource-teardown"&&N!=null){S({jsonrpc:"2.0",id:N,result:{}});return}O==="ping"&&N!=null&&S({jsonrpc:"2.0",id:N,result:{}})};return window.addEventListener("message",D),()=>{R=!0,window.removeEventListener("message",D)}},[a,M]),Kt("iframe",{ref:i,src:b,sandbox:"allow-scripts allow-forms allow-same-origin",className:u("rounded-md border border-border",s),style:{height:d||void 0,minWidth:c?`min(${c}px, 100%)`:void 0,width:"100%",border:"none",colorScheme:"auto"},title:"MCP App"})}import{Component as Vt}from"react";import{jsx as Ge,jsxs as qt}from"react/jsx-runtime";var ie=class extends Vt{state={hasError:!1};static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(e){console.warn("[WaniWani] Widget failed to render:",e.message)}render(){return this.state.hasError?qt("div",{className:"flex items-center justify-between rounded-md border border-border bg-muted/50 px-4 py-3 text-sm text-muted-foreground",children:[Ge("span",{children:"Widget failed to load"}),Ge("button",{type:"button",onClick:()=>this.setState({hasError:!1}),className:"text-xs font-medium text-primary hover:underline",children:"Retry"})]}):this.props.children}};import{Fragment as Gt,jsx as I,jsxs as _}from"react/jsx-runtime";function Jt(t){return t.replace(/[-_]/g," ").replace(/^\w/,e=>e.toUpperCase())}function le({messages:t,status:e,welcomeMessage:o,resourceEndpoint:n,isDark:r}){let s=e==="submitted"||e==="streaming",a=t[t.length-1],p=t.length>0,C=s&&(!p||a.role==="user");return _(Gt,{children:[o&&I(ne,{from:"assistant",children:I(se,{children:I(ae,{children:o})})}),t.map(i=>{let g=i.parts.filter(c=>c.type==="text"),m=i.parts.filter(c=>c.type==="reasoning"),v=i.parts.filter(c=>c.type==="file"),w=i.parts.filter(c=>"toolCallId"in c),d=i===a&&i.role==="assistant",T=g.length>0;return _(ne,{from:i.role,children:[m.map((c,l)=>I(Be,{text:c.text},`reasoning-${i.id}-${l}`)),w.map(c=>{let l="output"in c?c.output:void 0,h=l!==void 0?_e(l):void 0,P=l!==void 0?Ke(l):!1;return _("div",{children:[_(Oe,{defaultOpen:c.state==="output-available",children:[I(ze,{title:c.title??Jt(c.toolName),state:c.state}),_(We,{children:[I($e,{input:c.input}),l!==void 0&&I(Ve,{output:l,errorText:"errorText"in c?c.errorText:void 0})]})]}),h&&l!==void 0&&I(ie,{children:I(ve,{resourceUri:h,toolInput:c.input??{},toolResult:{content:l.content,structuredContent:l.structuredContent},resourceEndpoint:n,isDark:r,autoHeight:P})})]},c.toolCallId)}),_(se,{children:[v.length>0&&I(Ae,{files:v}),T?g.map((c,l)=>I(ae,{children:c.type==="text"?c.text:""},`${i.id}-${l}`)):d&&s&&I(be,{})]})]},i.id)}),C&&I(ne,{from:"assistant",children:I(se,{children:I(be,{})})})]})}import{jsx as we}from"react/jsx-runtime";function ue({suggestions:t,isLoading:e,onSelect:o,className:n,...r}){return t.length===0&&!e?null:we("div",{className:u("flex flex-wrap gap-2 px-3 py-2",n),...r,children:e?[0,1,2].map(s=>we("div",{className:"h-7 rounded-full bg-accent animate-pulse",style:{width:`${60+s*20}px`}},s)):t.map((s,a)=>we("button",{type:"button",onClick:()=>o(s),className:u("rounded-full border border-border bg-background px-3 py-1 text-xs","text-foreground hover:bg-accent hover:border-primary/30","transition-all duration-200 ease-out cursor-pointer","animate-[ww-fade-in_0.2s_ease-out_both]"),style:{animationDelay:`${a*50}ms`},children:s},s))})}import{useChat as Xt}from"@ai-sdk/react";import{DefaultChatTransport as Zt}from"ai";import{useCallback as Xe,useRef as Qt,useState as Yt}from"react";function ce(t){let{api:e="https://app.waniwani.ai/api/chat",headers:o,body:n,onMessageSent:r,onResponseReceived:s}=t,a=Qt(new Zt({api:e,headers:{...o},body:n})),{messages:p,sendMessage:C,status:i}=Xt({transport:a.current,onFinish(){s?.()},onError(h){console.warn("[WaniWani] Chat error:",h.message)}}),[g,m]=Yt(""),v=Xe(h=>{let P=!!h.text?.trim(),M=!!h.files?.length;(P||M)&&(C({text:h.text||"",files:h.files}),r?.(h.text||""),m(""))},[C,r]),w=Xe(h=>{m(h.target.value)},[]),d=i==="submitted"||i==="streaming",T=p[p.length-1],c=p.length>0,l=d&&(!c||T.role==="user");return{messages:p,status:i,text:g,setText:m,handleSubmit:v,handleTextChange:w,isLoading:d,showLoaderBubble:l,lastMessage:T,hasMessages:c,sendMessage:C}}import{useCallback as eo,useEffect as pe,useRef as Ze,useState as Qe}from"react";function to(t){try{let e=new URL(t);return e.pathname="/api/mcp/suggestions",e.toString()}catch{return"/api/mcp/suggestions"}}function me(t){let{messages:e,status:o,initialSuggestions:n,suggestions:r,api:s="https://app.waniwani.ai/api/chat",apiKey:a,headers:p}=t,[C,i]=Qe([]),[g,m]=Qe(!1),v=Ze(o),w=Ze(null),d=!!r,T=typeof r=="object"?r.count??3:3,c=e.some(M=>M.role==="user"),l=to(s),h=eo(()=>{i([]),w.current?.abort(),w.current=null},[]);pe(()=>{!c&&n?.length&&i(n)},[c,n]);let P=e[e.length-1];return pe(()=>{P?.role==="user"&&h()},[P,h]),pe(()=>{let M=v.current;if(v.current=o,M==="streaming"&&o==="ready"&&d){let b=new AbortController;w.current?.abort(),w.current=b,m(!0),fetch(l,{method:"POST",headers:{"Content-Type":"application/json",...a?{Authorization:`Bearer ${a}`}:{},...p},body:JSON.stringify({messages:e,count:T}),signal:b.signal}).then(f=>{if(!f.ok)throw new Error(`Suggestions API error: ${f.status}`);return f.json()}).then(f=>{b.signal.aborted||i(f.suggestions??[])}).catch(f=>{f.name!=="AbortError"&&console.warn("[WaniWani] Failed to fetch suggestions:",f)}).finally(()=>{b.signal.aborted||m(!1)})}},[o,d,l,a,e,T,p]),pe(()=>()=>{w.current?.abort()},[]),{suggestions:C,isLoading:g,clear:h}}var Ye={primaryColor:"#6366f1",primaryForeground:"#1f2937",backgroundColor:"#ffffff",textColor:"#1f2937",mutedColor:"#6b7280",borderColor:"#e5e7eb",assistantBubbleColor:"#f3f4f6",userBubbleColor:"#f4f4f4",inputBackgroundColor:"#f9fafb",borderRadius:16,messageBorderRadius:12,fontFamily:"system-ui, -apple-system, 'Segoe UI', sans-serif",headerBackgroundColor:"#ffffff",headerTextColor:"#1f2937",statusColor:"#22c55e",toolCardColor:"#f4f4f5"},oo={backgroundColor:"#212121",headerBackgroundColor:"#1e1e1e",headerTextColor:"#ececec",textColor:"#ececec",primaryForeground:"#ffffff",mutedColor:"#8e8ea0",borderColor:"#303030",assistantBubbleColor:"#2f2f2f",userBubbleColor:"#303030",inputBackgroundColor:"#2f2f2f",primaryColor:"#6366f1",statusColor:"#22c55e",toolCardColor:"#262626"},ro={primaryColor:["--ww-primary","--color-primary"],primaryForeground:["--ww-primary-fg","--color-primary-foreground"],backgroundColor:["--ww-bg","--color-background"],textColor:["--ww-text","--color-foreground","--color-accent-foreground"],mutedColor:["--ww-muted","--color-muted-foreground"],borderColor:["--ww-border","--color-border"],assistantBubbleColor:["--ww-assistant-bubble","--color-accent"],userBubbleColor:["--ww-user-bubble"],inputBackgroundColor:["--ww-input-bg","--color-input"],borderRadius:["--ww-radius","--radius"],messageBorderRadius:["--ww-msg-radius"],fontFamily:["--ww-font"],headerBackgroundColor:["--ww-header-bg"],headerTextColor:["--ww-header-text"],statusColor:["--ww-status"],toolCardColor:["--ww-tool-card","--color-tool-card"]};function V(t){return{...Ye,...t}}function de(t){let e=t.backgroundColor.replace("#",""),o=parseInt(e.substring(0,2),16),n=parseInt(e.substring(2,4),16),r=parseInt(e.substring(4,6),16);return(o*299+n*587+r*114)/1e3<128}function q(t){let e={};for(let[o,n]of Object.entries(ro)){let r=t[o],s=typeof r=="number"?`${r}px`:String(r);for(let a of n)e[a]=s}return e}import{jsx as B,jsxs as Te}from"react/jsx-runtime";var Pe=no(function(e,o){let{theme:n,width:r=600,expandedHeight:s=400,allowAttachments:a=!1,welcomeMessage:p,resourceEndpoint:C,api:i}=e,g=C??(i?`${i}/resource`:void 0),m=V(n),v=q(m),w=de(m),d=ce(e),T=me({messages:d.messages,status:d.status,initialSuggestions:e.initialSuggestions,suggestions:e.suggestions,api:e.api,apiKey:e.apiKey,headers:e.headers}),c=et(f=>{T.clear(),d.handleSubmit({text:f,files:[]})},[T.clear,d.handleSubmit]);ao(o,()=>({sendMessage:f=>{d.handleSubmit({text:f,files:[]})}}),[d.handleSubmit]);let[l,h]=lo(!1),P=io(null),M=l;so(()=>{if(!l)return;let f=x=>{P.current&&!P.current.contains(x.target)&&h(!1)};return document.addEventListener("mousedown",f),()=>document.removeEventListener("mousedown",f)},[l]);let b=et(()=>{h(!0)},[]);return Te("div",{ref:P,style:{...v,width:r},"data-waniwani-chat":"","data-waniwani-layout":"bar",...w?{"data-waniwani-dark":""}:{},className:"flex flex-col font-[family-name:var(--ww-font)] text-foreground",children:[B("div",{className:u("overflow-hidden bg-background/80 backdrop-blur-xl transition-all duration-300 ease-out",M?"opacity-100 translate-y-0":"opacity-0 translate-y-2 pointer-events-none max-h-0"),style:{...M?{maxHeight:s}:void 0,maskImage:"linear-gradient(to bottom, transparent, black 24px, black calc(100% - 16px), transparent), linear-gradient(to right, transparent, black 16px, black calc(100% - 16px), transparent)",maskComposite:"intersect",WebkitMaskImage:"linear-gradient(to bottom, transparent, black 24px, black calc(100% - 16px), transparent), linear-gradient(to right, transparent, black 16px, black calc(100% - 16px), transparent)",WebkitMaskComposite:"source-in"},children:Te(Z,{className:"flex-1",style:{height:s},children:[B(Q,{children:B(le,{messages:d.messages,status:d.status,welcomeMessage:p,resourceEndpoint:g,isDark:w})}),B(Y,{})]})}),B(ue,{suggestions:T.suggestions,isLoading:T.isLoading,onSelect:c}),B("div",{className:"shrink-0",children:B(ee,{onSubmit:d.handleSubmit,globalDrop:a,multiple:a,className:u("rounded-[var(--ww-radius)] shadow-sm transition-all duration-300 ease-out"),children:Te("div",{className:"flex items-center gap-1 px-3 py-2",children:[a&&B(re,{}),B(te,{onChange:d.handleTextChange,value:d.text,placeholder:"Ask anything...",onFocus:b,className:"min-h-0 py-1.5 px-2"}),B(oe,{status:d.status})]})})})]})});import{forwardRef as uo,useCallback as co,useImperativeHandle as po}from"react";import{jsx as L,jsxs as J}from"react/jsx-runtime";var mo=uo(function(e,o){let{theme:n,title:r="Assistant",subtitle:s,showStatus:a=!0,width:p=500,height:C=600,allowAttachments:i=!1,welcomeMessage:g,resourceEndpoint:m,api:v}=e,w=m??(v?`${v}/resource`:void 0),d=V(n),T=q(d),c=de(d),l=ce(e),h=me({messages:l.messages,status:l.status,initialSuggestions:e.initialSuggestions,suggestions:e.suggestions,api:e.api,apiKey:e.apiKey,headers:e.headers}),P=co(M=>{h.clear(),l.handleSubmit({text:M,files:[]})},[h.clear,l.handleSubmit]);return po(o,()=>({sendMessage:M=>{l.handleSubmit({text:M,files:[]})}}),[l.handleSubmit]),J("div",{style:{...T,width:p,height:C},"data-waniwani-chat":"","data-waniwani-layout":"card",...c?{"data-waniwani-dark":""}:{},className:"flex flex-col font-[family-name:var(--ww-font)] text-foreground bg-background rounded-[var(--ww-radius)] border border-border shadow-md overflow-hidden",children:[J("div",{className:"shrink-0 flex items-center gap-3 px-4 py-2 border-b border-border",style:{backgroundColor:d.headerBackgroundColor,color:d.headerTextColor},children:[a&&L("span",{className:"size-2.5 rounded-full bg-status"}),J("div",{className:"flex-1 min-w-0",children:[L("div",{className:"text-xs font-semibold truncate",children:r}),s&&L("div",{className:"text-[11px] text-muted-foreground truncate",children:s})]})]}),J(Z,{className:"flex-1 min-h-0 bg-background",children:[L(Q,{children:L(le,{messages:l.messages,status:l.status,welcomeMessage:g,resourceEndpoint:w,isDark:c})}),L(Y,{})]}),L(ue,{suggestions:h.suggestions,isLoading:h.isLoading,onSelect:P,className:"border-t border-border"}),L("div",{className:"shrink-0 border-t border-border bg-background",children:L(ee,{onSubmit:l.handleSubmit,globalDrop:i,multiple:i,className:u("rounded-none border-0"),children:J("div",{className:"flex items-center gap-1 px-3 py-2",children:[i&&L(re,{}),L(te,{onChange:l.handleTextChange,value:l.text,placeholder:"Ask anything...",className:"min-h-0 py-1.5 px-2"}),L(oe,{status:l.status})]})})})]})});export{Pe as ChatBar,mo as ChatCard,Pe as ChatWidget,oo as DARK_THEME,Ye as DEFAULT_THEME,ve as McpAppFrame,V as mergeTheme,q as themeToCSSProperties};
|
|
3
3
|
//# sourceMappingURL=index.js.map
|