@waniwani/sdk 0.0.12 → 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 +20 -2
- 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 +10 -2
- 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 -64
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.d.ts +267 -105
- 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 +7 -3
- 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
|
@@ -35,6 +35,10 @@ interface ChatTheme {
|
|
|
35
35
|
/** Tool call JSON section background. Defaults to light gray / #262626 in dark. */
|
|
36
36
|
toolCardColor?: string;
|
|
37
37
|
}
|
|
38
|
+
interface SuggestionsConfig {
|
|
39
|
+
/** Maximum number of AI suggestions to request. Defaults to 3. */
|
|
40
|
+
count?: number;
|
|
41
|
+
}
|
|
38
42
|
interface ChatBaseProps {
|
|
39
43
|
/** WaniWani project API key */
|
|
40
44
|
apiKey?: string;
|
|
@@ -56,6 +60,13 @@ interface ChatBaseProps {
|
|
|
56
60
|
onResponseReceived?: () => void;
|
|
57
61
|
/** Endpoint URL for fetching MCP app resources (HTML widgets). Defaults to "/api/mcp/resource" */
|
|
58
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;
|
|
59
70
|
}
|
|
60
71
|
interface ChatBarProps extends ChatBaseProps {
|
|
61
72
|
/** Chat bar width in pixels. Defaults to 600. */
|
|
@@ -99,8 +110,15 @@ interface McpAppFrameProps {
|
|
|
99
110
|
className?: string;
|
|
100
111
|
/** When true, the iframe height auto-adapts to its content. Set via `_meta.ui.autoHeight` in the tool result. */
|
|
101
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;
|
|
102
120
|
}
|
|
103
|
-
declare function McpAppFrame({ resourceUri, toolInput, toolResult, resourceEndpoint, isDark, className, autoHeight, }: McpAppFrameProps): react_jsx_runtime.JSX.Element;
|
|
121
|
+
declare function McpAppFrame({ resourceUri, toolInput, toolResult, resourceEndpoint, isDark, className, autoHeight, onOpenLink, onMessage, }: McpAppFrameProps): react_jsx_runtime.JSX.Element;
|
|
104
122
|
|
|
105
123
|
declare const ChatCard: react.ForwardRefExoticComponent<ChatCardProps & react.RefAttributes<ChatHandle>>;
|
|
106
124
|
|
|
@@ -109,4 +127,4 @@ declare const DARK_THEME: ChatTheme;
|
|
|
109
127
|
declare function mergeTheme(userTheme?: ChatTheme): Required<ChatTheme>;
|
|
110
128
|
declare function themeToCSSProperties(theme: Required<ChatTheme>): Record<string, string>;
|
|
111
129
|
|
|
112
|
-
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, 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{forwardRef as St,useCallback as Bt,useEffect as Dt,useImperativeHandle as Ft,useRef as Ut,useState as Ot}from"react";import{ArrowDownIcon as Ue}from"lucide-react";import{useCallback as Oe}from"react";import{StickToBottom as de,useStickToBottomContext as ze}from"use-stick-to-bottom";import{clsx as Be}from"clsx";import{twMerge as De}from"tailwind-merge";function i(...e){return De(Be(e))}import{jsx as Fe}from"react/jsx-runtime";var S=({className:e,variant:t="default",size:o="default",type:r="button",...n})=>Fe("button",{type:r,className:i("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 W}from"react/jsx-runtime";var V=({className:e,...t})=>W(de,{className:i("relative flex-1 overflow-y-hidden",e),initial:"smooth",resize:"smooth",role:"log",...t}),q=({className:e,...t})=>W(de.Content,{className:i("flex flex-col gap-8 p-4",e),...t}),J=({className:e,...t})=>{let{isAtBottom:o,scrollToBottom:r}=ze(),n=Oe(()=>{r()},[r]);return!o&&W(S,{className:i("absolute bottom-4 left-[50%] translate-x-[-50%] rounded-full",e),onClick:n,size:"icon",variant:"outline",...t,children:W(Ue,{className:"size-4"})})};import{ArrowUpIcon as je,LoaderIcon as $e,PaperclipIcon as _e,SquareIcon as We,XIcon as Ve}from"lucide-react";import{nanoid as qe}from"nanoid";import{createContext as Je,useCallback as R,useContext as Ke,useEffect as ne,useMemo as Ge,useRef as se,useState as fe}from"react";import{jsx as N,jsxs as be}from"react/jsx-runtime";var Xe=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}},ge=Je(null),he=()=>{let e=Ke(ge);if(!e)throw new Error("usePromptInputAttachments must be used within a PromptInput");return e},K=({className:e,accept:t,multiple:o,globalDrop:r,maxFiles:n,maxFileSize:l,onSubmit:a,children:p,...v})=>{let u=se(null),f=se(null),[g,m]=fe([]),w=se(g);ne(()=>{w.current=g},[g]);let P=R(()=>{u.current?.click()},[]),h=R(c=>{let y=[...c];if(y.length===0)return;let C=L=>l?L.size<=l:!0,T=y.filter(C);m(L=>{let A=typeof n=="number"?Math.max(0,n-L.length):void 0,D=typeof A=="number"?T.slice(0,A):T;return[...L,...D.map(U=>({filename:U.name,id:qe(),mediaType:U.type,type:"file",url:URL.createObjectURL(U)}))]})},[n,l]),s=R(c=>{m(y=>{let C=y.find(T=>T.id===c);return C?.url&&URL.revokeObjectURL(C.url),y.filter(T=>T.id!==c)})},[]),d=R(()=>{m(c=>{for(let y of c)y.url&&URL.revokeObjectURL(y.url);return[]})},[]);ne(()=>()=>{for(let c of w.current)c.url&&URL.revokeObjectURL(c.url)},[]);let b=R(c=>{c.currentTarget.files&&h(c.currentTarget.files),c.currentTarget.value=""},[h]);ne(()=>{if(!r)return;let c=C=>{C.dataTransfer?.types?.includes("Files")&&C.preventDefault()},y=C=>{C.dataTransfer?.types?.includes("Files")&&C.preventDefault(),C.dataTransfer?.files&&C.dataTransfer.files.length>0&&h(C.dataTransfer.files)};return document.addEventListener("dragover",c),document.addEventListener("drop",y),()=>{document.removeEventListener("dragover",c),document.removeEventListener("drop",y)}},[h,r]);let M=R(async c=>{c.preventDefault();let y=c.currentTarget,T=new FormData(y).get("message")||"";y.reset();let L=await Promise.all(g.map(async({id:A,...D})=>{if(D.url?.startsWith("blob:")){let U=await Xe(D.url);return{...D,url:U??D.url}}return D}));try{let A=a({files:L,text:T},c);A instanceof Promise&&await A,d()}catch{}},[g,a,d]),k=Ge(()=>({add:h,clear:d,files:g,openFileDialog:P,remove:s}),[g,h,s,d,P]);return be(ge.Provider,{value:k,children:[N("input",{accept:t,"aria-label":"Upload files",className:"hidden",multiple:o,onChange:b,ref:u,title:"Upload files",type:"file"}),N("form",{className:i("flex w-full flex-col rounded-lg border border-border bg-background",e),onSubmit:M,ref:f,...v,children:p})]})};var G=({onChange:e,onKeyDown:t,className:o,placeholder:r="What would you like to know?",...n})=>{let l=he(),[a,p]=fe(!1),v=R(f=>{if(t?.(f),!f.defaultPrevented){if(f.key==="Enter"){if(a||f.nativeEvent.isComposing||f.shiftKey)return;f.preventDefault();let{form:g}=f.currentTarget;if(g?.querySelector('button[type="submit"]')?.disabled)return;g?.requestSubmit()}if(f.key==="Backspace"&&f.currentTarget.value===""&&l.files.length>0){f.preventDefault();let g=l.files.at(-1);g&&l.remove(g.id)}}},[t,a,l]),u=R(f=>{let g=f.clipboardData?.items;if(!g)return;let m=[];for(let w of g)if(w.kind==="file"){let P=w.getAsFile();P&&m.push(P)}m.length>0&&(f.preventDefault(),l.add(m))},[l]);return N("textarea",{className:i("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:v,onPaste:u,placeholder:r,onChange:e,...n})},X=({className:e,status:t,onStop:o,onClick:r,children:n,...l})=>{let a=t==="submitted"||t==="streaming",p=N(je,{className:"size-4"});t==="submitted"?p=N($e,{className:"size-4 animate-spin"}):t==="streaming"&&(p=N(We,{className:"size-4"}));let v=R(u=>{if(a&&o){u.preventDefault(),o();return}r?.(u)},[a,o,r]);return N(S,{"aria-label":a?"Stop":"Submit",className:i("bg-foreground text-background hover:bg-foreground",e),onClick:v,size:"icon-sm",type:a&&o?"button":"submit",variant:"ghost",...l,children:n??p})},Q=({className:e,children:t,...o})=>{let r=he();return r.files.length>0?be(S,{className:i("group relative",e),onClick:()=>r.clear(),size:"icon-sm",type:"button",variant:"ghost","aria-label":"Remove all attachments",...o,children:[N("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}),N(Ve,{className:"absolute size-4 opacity-0 transition-opacity group-hover:opacity-100"})]}):N(S,{className:i(e),onClick:()=>r.openFileDialog(),size:"icon-sm",type:"button",variant:"ghost",...o,children:t??N(_e,{className:"size-4"})})};import{FileIcon as Qe}from"lucide-react";import{jsx as O,jsxs as Ze}from"react/jsx-runtime";var xe=({files:e,className:t,...o})=>e.length===0?null:O("div",{className:i("flex flex-wrap gap-1.5",t),...o,children:e.map((r,n)=>O(Ye,{file:r},n))});function Ye({file:e}){return e.mediaType?.startsWith("image/")&&e.url?O("img",{src:e.url,alt:e.filename??"attachment",className:"h-16 max-w-32 rounded object-cover"}):Ze("span",{className:"inline-flex items-center gap-1.5 rounded bg-background/20 px-2 py-1 text-xs",children:[O(Qe,{className:"size-3 shrink-0"}),O("span",{className:"max-w-24 truncate",children:e.filename??"file"})]})}import{jsx as Ce}from"react/jsx-runtime";var ae=({className:e,size:t=5,...o})=>Ce("div",{className:i("flex items-center gap-1",e),...o,children:[0,1,2].map(r=>Ce("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 et}from"@streamdown/cjk";import{code as tt}from"@streamdown/code";import{memo as ot}from"react";import{Streamdown as rt}from"streamdown";import{jsx as ie}from"react/jsx-runtime";var Y=({className:e,from:t,...o})=>ie("div",{className:i("group flex w-full max-w-[95%] flex-col gap-2",t==="user"?"is-user ml-auto justify-end":"is-assistant",e),...o}),Z=({children:e,className:t,...o})=>ie("div",{className:i("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",t),...o,children:e}),nt={cjk:et,code:tt},ee=ot(({className:e,...t})=>ie(rt,{className:i("size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0",e),plugins:nt,...t}),(e,t)=>e.children===t.children);ee.displayName="MessageResponse";import{jsx as st}from"react/jsx-runtime";function ve({className:e,text:t,...o}){return t?st("pre",{className:i("mb-2 overflow-x-auto whitespace-pre-wrap break-words text-xs font-mono text-muted-foreground",e),...o,children:t}):null}import{BracesIcon as at,CheckIcon as it,ChevronDownIcon as lt,ChevronRightIcon as ut,ClipboardCopyIcon as pt,ServerIcon as No}from"lucide-react";import{createContext as ct,useCallback as mt,useContext as Te,useEffect as dt,useMemo as ft,useRef as gt,useState as le}from"react";import{Fragment as ye,jsx as x,jsxs as B}from"react/jsx-runtime";function ht(e,t=80){if(e==null)return String(e);if(typeof e!="object")return String(e).slice(0,t);if(Array.isArray(e))return`Array(${e.length})`;let o=JSON.stringify(e);if(o.length<=t)return o;let r=Object.entries(e),n=[],l=t-2;for(let[a,p]of r){if(l<=8)break;let v=a.length>4?`${a.slice(0,4)}\u2026`:a,u;typeof p=="string"?u=p.length>2?`'${p.slice(0,1)}\u2026`:`'${p}'`:Array.isArray(p)?u=`Array(${p.length})`:typeof p=="object"&&p!==null?u="{\u2026}":u=String(p);let f=`${v}\u2009${u}`;n.push(f),l-=f.length+3}return`{${n.join(", ")}}`}function bt({text:e,className:t}){let[o,r]=le(!1),n=gt(null);dt(()=>()=>{n.current&&clearTimeout(n.current)},[]);let l=mt(async a=>{a.stopPropagation();try{await navigator.clipboard.writeText(e),r(!0),n.current&&clearTimeout(n.current),n.current=setTimeout(()=>r(!1),2e3)}catch{}},[e]);return x(S,{variant:"ghost",size:"sm",onClick:l,className:i("h-auto gap-1 px-1.5 py-0.5 text-xs text-muted-foreground hover:text-foreground",t),children:o?B(ye,{children:[x(it,{className:"size-3.5"}),x("span",{children:"Copied"})]}):B(ye,{children:[x(pt,{className:"size-3.5"}),x("span",{children:"Copy"})]})})}function we({data:e,label:t,className:o,...r}){let[n,l]=le(!1),a=ft(()=>JSON.stringify(e,null,2),[e]),p=ht(e);return B("div",{className:i("rounded-lg bg-tool-card",o),...r,children:[B("div",{className:"flex items-center justify-between px-3 pt-2.5 pb-1.5",children:[x("span",{className:"text-xs font-medium text-muted-foreground",children:t}),x(bt,{text:a})]}),B("button",{type:"button",onClick:()=>l(v=>!v),className:"flex w-full items-start gap-2 px-3 pb-3 text-left",children:[x(ut,{className:i("mt-0.5 size-3.5 shrink-0 text-muted-foreground transition-transform duration-150",n&&"rotate-90")}),n?x("pre",{className:"overflow-x-auto text-xs font-mono text-foreground whitespace-pre-wrap break-all",children:x("code",{children:a})}):x("span",{className:"truncate text-xs font-mono text-foreground/80",children:p})]})]})}var ue=ct({open:!1,toggle:()=>{}});function Pe({className:e,defaultOpen:t=!1,children:o,...r}){let[n,l]=le(t);return x(ue.Provider,{value:{open:n,toggle:()=>l(a=>!a)},children:x("div",{className:i("mb-4 w-full",e),"data-state":n?"open":"closed",...r,children:o})})}function Me({className:e,title:t,state:o,...r}){let{open:n,toggle:l}=Te(ue),a=o==="input-available"||o==="input-streaming";return B("button",{type:"button",onClick:l,className:i("flex w-full items-center justify-between gap-3 py-1.5",e),"aria-expanded":n,...r,children:[B("div",{className:"flex min-w-0 items-center gap-2",children:[x(at,{className:"size-4 shrink-0 text-muted-foreground"}),x("span",{className:"truncate text-sm font-medium",children:t}),a&&x("span",{className:"size-2 shrink-0 rounded-full bg-primary animate-pulse"})]}),x(lt,{className:i("size-4 shrink-0 text-muted-foreground transition-transform duration-200",n&&"rotate-180")})]})}function ke({className:e,children:t,...o}){let{open:r}=Te(ue);return x("div",{className:i("grid transition-[grid-template-rows,opacity] duration-200 ease-out",r?"grid-rows-[1fr] opacity-100":"grid-rows-[0fr] opacity-0"),children:x("div",{className:"min-h-0 overflow-hidden",children:x("div",{className:i("mt-2 space-y-3 rounded-lg border border-border bg-background p-3",e),...o,children:t})})})}function Ie({className:e,input:t,...o}){return x(we,{data:t,label:"Request",className:e,...o})}function Ne(e){if(typeof e!="object"||e===null)return;let t=e._meta;if(typeof t!="object"||t===null)return;let o=t.ui;if(!(typeof o!="object"||o===null))return o}function Ee(e){let t=Ne(e)?.resourceUri;return typeof t=="string"?t:void 0}function Le(e){return Ne(e)?.autoHeight===!0}function Re({className:e,output:t,errorText:o,...r}){return t||o?o?B("div",{className:i("space-y-2",e),...r,children:[x("h4",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:"Error"}),x("div",{className:"rounded-lg bg-destructive/10 p-3 text-xs text-destructive",children:o})]}):x(we,{data:t,label:"Response",className:e,...r}):null}import{useCallback as xt,useEffect as He,useMemo as Ct,useRef as z,useState as vt}from"react";import{jsx as Mt}from"react/jsx-runtime";var yt="/api/mcp/resource",Tt=500,wt=300,Pt="2026-01-26";function pe({resourceUri:e,toolInput:t,toolResult:o,resourceEndpoint:r=yt,isDark:n=!1,className:l,autoHeight:a=!0}){let p=z(null),v=z(t),u=z(o),f=z(!1),[g,m]=vt(wt);v.current=t,u.current=o;let w=xt(s=>a?Math.max(s,0):Math.min(Math.max(s,50),Tt),[a]),P=Ct(()=>`${r}?uri=${encodeURIComponent(e)}`,[r,e]),h=z(n);return h.current=n,He(()=>{let s=p.current;if(!s)return;let d=!1,b=k=>{s.contentWindow?.postMessage(k,"*")},M=k=>{if(d||k.source!==s.contentWindow)return;let c=k.data;if(!c||typeof c!="object"||c.jsonrpc!=="2.0")return;let y=c.method,C=c.id;if(y==="ui/initialize"&&C!=null){b({jsonrpc:"2.0",id:C,result:{protocolVersion:c.params?.protocolVersion??Pt,hostInfo:{name:"WaniWani Chat",version:"1.0.0"},hostCapabilities:{},hostContext:{theme:h.current?"dark":"light",autoHeight:a}}});return}if(y==="ui/notifications/initialized"){let T=v.current,L=u.current;b({jsonrpc:"2.0",method:"ui/notifications/tool-input",params:{arguments:T}});let A=L.content??[{type:"text",text:JSON.stringify(L)}];b({jsonrpc:"2.0",method:"ui/notifications/tool-result",params:{content:A,structuredContent:L.structuredContent}});return}if(y==="ui/notifications/size-changed"){if(f.current)return;let T=c.params?.height;typeof T=="number"&&!d&&m(w(T));return}if(y==="ui/open-link"&&C!=null){let T=c.params?.url;typeof T=="string"&&window.open(T,"_blank","noopener,noreferrer"),b({jsonrpc:"2.0",id:C,result:{}});return}y==="ping"&&C!=null&&b({jsonrpc:"2.0",id:C,result:{}})};return window.addEventListener("message",M),()=>{d=!0,window.removeEventListener("message",M)}},[a,w]),He(()=>{if(!a)return;let s=p.current;if(!s)return;let d,b=!1,M=()=>{if(!b)try{let k=s.contentDocument?.body;if(!k)return;d=new ResizeObserver(()=>{if(b)return;let c=s.contentDocument?.defaultView?.getComputedStyle(k),y=Number.parseInt(c?.marginTop??"0",10)||0,C=Number.parseInt(c?.marginBottom??"0",10)||0,T=Math.max(k.scrollHeight,k.offsetHeight)+y+C;T>0&&m(T)}),d.observe(k)}catch{}};return s.addEventListener("load",M),M(),()=>{b=!0,d?.disconnect(),s.removeEventListener("load",M)}},[a]),Mt("iframe",{ref:p,src:P,sandbox:"allow-scripts allow-forms allow-same-origin",className:i("w-full rounded-md border border-border",l),style:{height:g||void 0,border:"none",colorScheme:"auto"},title:"MCP App"})}import{Fragment as It,jsx as I,jsxs as F}from"react/jsx-runtime";function kt(e){return e.replace(/[-_]/g," ").replace(/^\w/,t=>t.toUpperCase())}function te({messages:e,status:t,welcomeMessage:o,resourceEndpoint:r,isDark:n}){let l=t==="submitted"||t==="streaming",a=e[e.length-1],p=e.length>0,v=l&&(!p||a.role==="user");return F(It,{children:[o&&I(Y,{from:"assistant",children:I(Z,{children:I(ee,{children:o})})}),e.map(u=>{let f=u.parts.filter(s=>s.type==="text"),g=u.parts.filter(s=>s.type==="reasoning"),m=u.parts.filter(s=>s.type==="file"),w=u.parts.filter(s=>"toolCallId"in s),P=u===a&&u.role==="assistant",h=f.length>0;return F(Y,{from:u.role,children:[g.map((s,d)=>I(ve,{text:s.text},`reasoning-${u.id}-${d}`)),w.map(s=>{let d="output"in s?s.output:void 0,b=d!==void 0?Ee(d):void 0,M=d!==void 0?Le(d):!1;return F("div",{children:[F(Pe,{defaultOpen:s.state==="output-available",children:[I(Me,{title:s.title??kt(s.toolName),state:s.state}),F(ke,{children:[I(Ie,{input:s.input}),d!==void 0&&I(Re,{output:d,errorText:"errorText"in s?s.errorText:void 0})]})]}),b&&d!==void 0&&I(pe,{resourceUri:b,toolInput:s.input??{},toolResult:{content:d.content,structuredContent:d.structuredContent},resourceEndpoint:r,isDark:n,autoHeight:M})]},s.toolCallId)}),F(Z,{children:[m.length>0&&I(xe,{files:m}),h?f.map((s,d)=>I(ee,{children:s.type==="text"?s.text:""},`${u.id}-${d}`)):P&&l&&I(ae,{})]})]},u.id)}),v&&I(Y,{from:"assistant",children:I(Z,{children:I(ae,{})})})]})}import{useChat as Nt}from"@ai-sdk/react";import{DefaultChatTransport as Et}from"ai";import{useCallback as Ae,useRef as Lt,useState as Rt}from"react";function oe(e){let{api:t="https://app.waniwani.ai/api/chat",headers:o,body:r,onMessageSent:n,onResponseReceived:l}=e,a=Lt(new Et({api:t,headers:{...o},body:r})),{messages:p,sendMessage:v,status:u}=Nt({transport:a.current,onFinish(){l?.()}}),[f,g]=Rt(""),m=Ae(b=>{let M=!!b.text?.trim(),k=!!b.files?.length;(M||k)&&(v({text:b.text||"",files:b.files}),n?.(b.text||""),g(""))},[v,n]),w=Ae(b=>{g(b.target.value)},[]),P=u==="submitted"||u==="streaming",h=p[p.length-1],s=p.length>0,d=P&&(!s||h.role==="user");return{messages:p,status:u,text:f,setText:g,handleSubmit:m,handleTextChange:w,isLoading:P,showLoaderBubble:d,lastMessage:h,hasMessages:s,sendMessage:v}}var Se={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"},Ht={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"},At={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 j(e){return{...Se,...e}}function re(e){let t=e.backgroundColor.replace("#",""),o=parseInt(t.substring(0,2),16),r=parseInt(t.substring(2,4),16),n=parseInt(t.substring(4,6),16);return(o*299+r*587+n*114)/1e3<128}function $(e){let t={};for(let[o,r]of Object.entries(At)){let n=e[o],l=typeof n=="number"?`${n}px`:String(n);for(let a of r)t[a]=l}return t}import{jsx as H,jsxs as ce}from"react/jsx-runtime";var me=St(function(t,o){let{theme:r,width:n=600,expandedHeight:l=400,allowAttachments:a=!1,welcomeMessage:p,resourceEndpoint:v}=t,u=j(r),f=$(u),g=re(u),m=oe(t);Ft(o,()=>({sendMessage:b=>{m.handleSubmit({text:b,files:[]})}}),[m.handleSubmit]);let[w,P]=Ot(!1),h=Ut(null),s=w;Dt(()=>{if(!w)return;let b=M=>{h.current&&!h.current.contains(M.target)&&P(!1)};return document.addEventListener("mousedown",b),()=>document.removeEventListener("mousedown",b)},[w]);let d=Bt(()=>{P(!0)},[]);return ce("div",{ref:h,style:{...f,width:n},"data-waniwani-chat":"","data-waniwani-layout":"bar",...g?{"data-waniwani-dark":""}:{},className:"flex flex-col font-[family-name:var(--ww-font)] text-foreground",children:[H("div",{className:i("overflow-hidden bg-background/80 backdrop-blur-xl transition-all duration-300 ease-out",s?"opacity-100 translate-y-0":"opacity-0 translate-y-2 pointer-events-none max-h-0"),style:{...s?{maxHeight:l}: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:ce(V,{className:"flex-1",style:{height:l},children:[H(q,{children:H(te,{messages:m.messages,status:m.status,welcomeMessage:p,resourceEndpoint:v,isDark:g})}),H(J,{})]})}),H("div",{className:"shrink-0",children:H(K,{onSubmit:m.handleSubmit,globalDrop:a,multiple:a,className:i("rounded-[var(--ww-radius)] shadow-sm transition-all duration-300 ease-out"),children:ce("div",{className:"flex items-center gap-1 px-3 py-2",children:[a&&H(Q,{}),H(G,{onChange:m.handleTextChange,value:m.text,placeholder:"Ask anything...",onFocus:d,className:"min-h-0 py-1.5 px-2"}),H(X,{status:m.status})]})})})]})});import{forwardRef as zt,useImperativeHandle as jt}from"react";import{jsx as E,jsxs as _}from"react/jsx-runtime";var $t=zt(function(t,o){let{theme:r,title:n="Assistant",subtitle:l,showStatus:a=!0,width:p=500,height:v=600,allowAttachments:u=!1,welcomeMessage:f,resourceEndpoint:g}=t,m=j(r),w=$(m),P=re(m),h=oe(t);return jt(o,()=>({sendMessage:s=>{h.handleSubmit({text:s,files:[]})}}),[h.handleSubmit]),_("div",{style:{...w,width:p,height:v},"data-waniwani-chat":"","data-waniwani-layout":"card",...P?{"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:[_("div",{className:"shrink-0 flex items-center gap-3 px-4 py-2 border-b border-border",style:{backgroundColor:m.headerBackgroundColor,color:m.headerTextColor},children:[a&&E("span",{className:"size-2.5 rounded-full bg-status"}),_("div",{className:"flex-1 min-w-0",children:[E("div",{className:"text-xs font-semibold truncate",children:n}),l&&E("div",{className:"text-[11px] text-muted-foreground truncate",children:l})]})]}),_(V,{className:"flex-1 min-h-0 bg-background",children:[E(q,{children:E(te,{messages:h.messages,status:h.status,welcomeMessage:f,resourceEndpoint:g,isDark:P})}),E(J,{})]}),E("div",{className:"shrink-0 border-t border-border bg-background",children:E(K,{onSubmit:h.handleSubmit,globalDrop:u,multiple:u,className:i("rounded-none border-0"),children:_("div",{className:"flex items-center gap-1 px-3 py-2",children:[u&&E(Q,{}),E(G,{onChange:h.handleTextChange,value:h.text,placeholder:"Ask anything...",className:"min-h-0 py-1.5 px-2"}),E(X,{status:h.status})]})})})]})});export{me as ChatBar,$t as ChatCard,me as ChatWidget,Ht as DARK_THEME,Se as DEFAULT_THEME,pe as McpAppFrame,j as mergeTheme,$ 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
|