@frankieai/react 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/frankie.css +1 -1
- package/dist/index.cjs +200 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +43 -6
- package/dist/index.d.ts +43 -6
- package/dist/index.js +208 -44
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/chat/ChatPanel.tsx +9 -1
- package/src/components/chat/Composer.tsx +190 -27
- package/src/components/chat/MessageBubble.tsx +20 -4
- package/src/hooks/useFrankieChat.ts +31 -8
- package/src/index.ts +2 -2
- package/src/lib/client.ts +12 -1
- package/src/lib/messages.ts +9 -2
- package/src/widget.test.tsx +4 -0
package/dist/frankie.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
|
|
2
|
-
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid}}}@layer theme{:root,:host{--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--font-weight-semibold:600;--leading-tight:1.25;--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer components{.frankie-root{--frankie-background:#fff;--frankie-foreground:#0a0a0a;--frankie-primary:#171717;--frankie-primary-foreground:#fafafa;--frankie-secondary:#f5f5f5;--frankie-secondary-foreground:#171717;--frankie-muted:#f5f5f5;--frankie-muted-foreground:#737373;--frankie-border:#e5e5e5;--frankie-radius:.625rem;--frankie-font:ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;font-family:var(--frankie-font);color:var(--frankie-foreground);-webkit-font-smoothing:antialiased;line-height:1.5}.frankie-root.dark{--frankie-background:#0a0a0a;--frankie-foreground:#fafafa;--frankie-primary:#fafafa;--frankie-primary-foreground:#171717;--frankie-secondary:#262626;--frankie-secondary-foreground:#fafafa;--frankie-muted:#262626;--frankie-muted-foreground:#a3a3a3;--frankie-border:#262626}.frankie-root,.frankie-root *,.frankie-root :before,.frankie-root :after{box-sizing:border-box}.frankie-root button,.frankie-root textarea,.frankie-root input{font:inherit;color:inherit;margin:0}.frankie-root textarea{background-color:var(--frankie-background)}.frankie-focus:focus-visible{outline:2px solid var(--frankie-primary);outline-offset:2px}.frankie-scroll{scrollbar-width:thin;scrollbar-color:var(--frankie-border) transparent}.frankie-prose>*+*{margin-top:.5rem}.frankie-prose p{white-space:pre-wrap;overflow-wrap:anywhere;margin:0}.frankie-prose ul,.frankie-prose ol{flex-direction:column;gap:.25rem;margin:0;padding-left:1.15rem;display:flex}.frankie-prose ul{list-style:outside}.frankie-prose ol{list-style:decimal}.frankie-prose a{color:var(--frankie-primary);text-underline-offset:2px;text-decoration:underline}.frankie-prose code{background-color:var(--frankie-muted);border-radius:.25rem;padding:.1em .3em;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,monospace;font-size:.85em}.frankie-prose pre{border-radius:var(--frankie-radius);background-color:var(--frankie-muted);margin:0;padding:.625rem .75rem;overflow-x:auto}.frankie-prose pre code{background:0 0;padding:0}}@layer utilities{.fixed{position:fixed}.isolate{isolation:isolate}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.flex{display:flex}.inline{display:inline}.inline-flex{display:inline-flex}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-12{width:calc(var(--spacing) * 12);height:calc(var(--spacing) * 12)}.size-full{width:100%;height:100%}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-\[32rem\]{height:32rem}.h-full{height:100%}.h-px{height:1px}.min-h-\[2\.25rem\]{min-height:2.25rem}.w-\[22rem\]{width:22rem}.w-full{width:100%}.max-w-\[85\%\]{max-width:85%}.max-w-\[calc\(100vw-2rem\)\]{max-width:calc(100vw - 2rem)}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.resize-none{resize:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:var(--spacing)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.overscroll-contain{overscroll-behavior:contain}.rounded-\[calc\(var\(--frankie-radius\)\+4px\)\]{border-radius:calc(var(--frankie-radius) + 4px)}.rounded-\[calc\(var\(--frankie-radius\)-2px\)\]{border-radius:calc(var(--frankie-radius) - 2px)}.rounded-\[var\(--frankie-radius\)\]{border-radius:var(--frankie-radius)}.rounded-full{border-radius:3.40282e38px}.rounded-none{border-radius:0}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-border{border-color:var(--frankie-border)}.border-transparent{border-color:#0000}.bg-background{background-color:var(--frankie-background)}.bg-border{background-color:var(--frankie-border)}.bg-emerald-500\/10{background-color:#00bb7f1a}@supports (color:color-mix(in lab, red, red)){.bg-emerald-500\/10{background-color:color-mix(in oklab, var(--color-emerald-500) 10%, transparent)}}.bg-muted{background-color:var(--frankie-muted)}.bg-muted-foreground{background-color:var(--frankie-muted-foreground)}.bg-primary{background-color:var(--frankie-primary)}.bg-red-500\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab, red, red)){.bg-red-500\/10{background-color:color-mix(in oklab, var(--color-red-500) 10%, transparent)}}.bg-secondary{background-color:var(--frankie-secondary)}.object-cover{object-fit:cover}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.625rem\]{font-size:.625rem}.text-\[0\.6875rem\]{font-size:.6875rem}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-nowrap{white-space:nowrap}.text-emerald-600{color:var(--color-emerald-600)}.text-foreground{color:var(--frankie-foreground)}.text-muted-foreground{color:var(--frankie-muted-foreground)}.text-primary{color:var(--frankie-primary)}.text-primary-foreground{color:var(--frankie-primary-foreground)}.text-red-600{color:var(--color-red-600)}.text-secondary-foreground{color:var(--frankie-secondary-foreground)}.underline-offset-4{text-underline-offset:4px}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.placeholder\:text-muted-foreground::placeholder{color:var(--frankie-muted-foreground)}@media (hover:hover){.hover\:bg-muted:hover{background-color:var(--frankie-muted)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-90:hover{opacity:.9}}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.dark\:text-emerald-400:where(.dark,.dark *){color:var(--color-emerald-400)}.dark\:text-red-400:where(.dark,.dark *){color:var(--color-red-400)}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid}}}@layer theme{:root,:host{--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--font-weight-semibold:600;--leading-tight:1.25;--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer components{.frankie-root{--frankie-background:#fff;--frankie-foreground:#0a0a0a;--frankie-primary:#171717;--frankie-primary-foreground:#fafafa;--frankie-secondary:#f5f5f5;--frankie-secondary-foreground:#171717;--frankie-muted:#f5f5f5;--frankie-muted-foreground:#737373;--frankie-border:#e5e5e5;--frankie-radius:.625rem;--frankie-font:ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;font-family:var(--frankie-font);color:var(--frankie-foreground);-webkit-font-smoothing:antialiased;line-height:1.5}.frankie-root.dark{--frankie-background:#0a0a0a;--frankie-foreground:#fafafa;--frankie-primary:#fafafa;--frankie-primary-foreground:#171717;--frankie-secondary:#262626;--frankie-secondary-foreground:#fafafa;--frankie-muted:#262626;--frankie-muted-foreground:#a3a3a3;--frankie-border:#262626}.frankie-root,.frankie-root *,.frankie-root :before,.frankie-root :after{box-sizing:border-box}.frankie-root button,.frankie-root textarea,.frankie-root input{font:inherit;color:inherit;margin:0}.frankie-root textarea{background-color:var(--frankie-background)}.frankie-focus:focus-visible{outline:2px solid var(--frankie-primary);outline-offset:2px}.frankie-scroll{scrollbar-width:thin;scrollbar-color:var(--frankie-border) transparent}.frankie-prose>*+*{margin-top:.5rem}.frankie-prose p{white-space:pre-wrap;overflow-wrap:anywhere;margin:0}.frankie-prose ul,.frankie-prose ol{flex-direction:column;gap:.25rem;margin:0;padding-left:1.15rem;display:flex}.frankie-prose ul{list-style:outside}.frankie-prose ol{list-style:decimal}.frankie-prose a{color:var(--frankie-primary);text-underline-offset:2px;text-decoration:underline}.frankie-prose code{background-color:var(--frankie-muted);border-radius:.25rem;padding:.1em .3em;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,monospace;font-size:.85em}.frankie-prose pre{border-radius:var(--frankie-radius);background-color:var(--frankie-muted);margin:0;padding:.625rem .75rem;overflow-x:auto}.frankie-prose pre code{background:0 0;padding:0}}@layer utilities{.fixed{position:fixed}.isolate{isolation:isolate}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.flex{display:flex}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-12{width:calc(var(--spacing) * 12);height:calc(var(--spacing) * 12)}.size-full{width:100%;height:100%}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-\[32rem\]{height:32rem}.h-full{height:100%}.h-px{height:1px}.min-h-\[2\.25rem\]{min-height:2.25rem}.w-\[22rem\]{width:22rem}.w-full{width:100%}.max-w-\[8rem\]{max-width:8rem}.max-w-\[12rem\]{max-width:12rem}.max-w-\[14rem\]{max-width:14rem}.max-w-\[85\%\]{max-width:85%}.max-w-\[calc\(100vw-2rem\)\]{max-width:calc(100vw - 2rem)}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.resize-none{resize:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.overscroll-contain{overscroll-behavior:contain}.rounded-\[calc\(var\(--frankie-radius\)\+4px\)\]{border-radius:calc(var(--frankie-radius) + 4px)}.rounded-\[calc\(var\(--frankie-radius\)-2px\)\]{border-radius:calc(var(--frankie-radius) - 2px)}.rounded-\[var\(--frankie-radius\)\]{border-radius:var(--frankie-radius)}.rounded-full{border-radius:3.40282e38px}.rounded-none{border-radius:0}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-border{border-color:var(--frankie-border)}.border-transparent{border-color:#0000}.bg-background{background-color:var(--frankie-background)}.bg-border{background-color:var(--frankie-border)}.bg-emerald-500\/10{background-color:#00bb7f1a}@supports (color:color-mix(in lab, red, red)){.bg-emerald-500\/10{background-color:color-mix(in oklab, var(--color-emerald-500) 10%, transparent)}}.bg-muted{background-color:var(--frankie-muted)}.bg-muted-foreground{background-color:var(--frankie-muted-foreground)}.bg-primary{background-color:var(--frankie-primary)}.bg-red-500\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab, red, red)){.bg-red-500\/10{background-color:color-mix(in oklab, var(--color-red-500) 10%, transparent)}}.bg-secondary{background-color:var(--frankie-secondary)}.object-cover{object-fit:cover}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.625rem\]{font-size:.625rem}.text-\[0\.6875rem\]{font-size:.6875rem}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-nowrap{white-space:nowrap}.text-emerald-600{color:var(--color-emerald-600)}.text-foreground{color:var(--frankie-foreground)}.text-muted-foreground{color:var(--frankie-muted-foreground)}.text-primary{color:var(--frankie-primary)}.text-primary-foreground{color:var(--frankie-primary-foreground)}.text-red-600{color:var(--color-red-600)}.text-secondary-foreground{color:var(--frankie-secondary-foreground)}.underline-offset-4{text-underline-offset:4px}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.placeholder\:text-muted-foreground::placeholder{color:var(--frankie-muted-foreground)}@media (hover:hover){.hover\:bg-muted:hover{background-color:var(--frankie-muted)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-90:hover{opacity:.9}.hover\:opacity-100:hover{opacity:1}}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.dark\:text-emerald-400:where(.dark,.dark *){color:var(--color-emerald-400)}.dark\:text-red-400:where(.dark,.dark *){color:var(--color-red-400)}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}
|
package/dist/index.cjs
CHANGED
|
@@ -152,7 +152,9 @@ var FrankieClient = class {
|
|
|
152
152
|
const body = {
|
|
153
153
|
sessionId: session.sessionId,
|
|
154
154
|
message: input.message,
|
|
155
|
-
...input.context ? { context: input.context } : {}
|
|
155
|
+
...input.context ? { context: input.context } : {},
|
|
156
|
+
...input.model ? { model: input.model } : {},
|
|
157
|
+
...input.attachments?.length ? { attachments: input.attachments } : {}
|
|
156
158
|
};
|
|
157
159
|
const response = await this.doFetch(`${this.baseUrl}/v1/chat`, {
|
|
158
160
|
method: "POST",
|
|
@@ -346,8 +348,8 @@ function fallbackText(stopReason) {
|
|
|
346
348
|
function newAssistantMessage(id) {
|
|
347
349
|
return { id, role: "assistant", text: "", thinking: "", tools: [], status: "streaming", createdAt: Date.now() };
|
|
348
350
|
}
|
|
349
|
-
function newUserMessage(id, text) {
|
|
350
|
-
return { id, role: "user", text, createdAt: Date.now() };
|
|
351
|
+
function newUserMessage(id, text, attachments) {
|
|
352
|
+
return { id, role: "user", text, ...attachments?.length ? { attachments } : {}, createdAt: Date.now() };
|
|
351
353
|
}
|
|
352
354
|
|
|
353
355
|
// src/hooks/useFrankieChat.ts
|
|
@@ -393,24 +395,39 @@ function useFrankieChat() {
|
|
|
393
395
|
);
|
|
394
396
|
}, []);
|
|
395
397
|
const send = (0, import_react2.useCallback)(
|
|
396
|
-
async (text) => {
|
|
398
|
+
async (text, opts) => {
|
|
397
399
|
const trimmed = text.trim();
|
|
398
|
-
|
|
400
|
+
const attachments = opts?.attachments ?? [];
|
|
401
|
+
if (!trimmed && attachments.length === 0 || busy) return;
|
|
402
|
+
const outgoing = trimmed || "Please take a look at the attached file(s).";
|
|
399
403
|
const assistantId = nextId("a");
|
|
400
404
|
setError(void 0);
|
|
401
405
|
setBusy(true);
|
|
402
406
|
setMessages((current) => [
|
|
403
407
|
...current,
|
|
404
|
-
newUserMessage(
|
|
408
|
+
newUserMessage(
|
|
409
|
+
nextId("u"),
|
|
410
|
+
trimmed,
|
|
411
|
+
attachments.map((file) => ({ name: file.name, mimeType: file.mimeType }))
|
|
412
|
+
),
|
|
405
413
|
newAssistantMessage(assistantId)
|
|
406
414
|
]);
|
|
407
415
|
const abort = new AbortController();
|
|
408
416
|
abortRef.current = abort;
|
|
409
417
|
try {
|
|
410
|
-
await client.send(
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
418
|
+
await client.send(
|
|
419
|
+
{
|
|
420
|
+
message: outgoing,
|
|
421
|
+
...context ? { context } : {},
|
|
422
|
+
...opts?.model ? { model: opts.model } : {},
|
|
423
|
+
...attachments.length ? { attachments } : {},
|
|
424
|
+
signal: abort.signal
|
|
425
|
+
},
|
|
426
|
+
(event) => {
|
|
427
|
+
if (event.type === "ping" || event.type === "session") return;
|
|
428
|
+
patchAssistant(assistantId, (message) => applyEvent(message, event));
|
|
429
|
+
}
|
|
430
|
+
);
|
|
414
431
|
} catch (caught) {
|
|
415
432
|
if (abort.signal.aborted) {
|
|
416
433
|
patchAssistant(assistantId, (message) => ({
|
|
@@ -452,7 +469,7 @@ function useFrankieChat() {
|
|
|
452
469
|
}
|
|
453
470
|
|
|
454
471
|
// src/components/chat/FrankieWidget.tsx
|
|
455
|
-
var
|
|
472
|
+
var import_lucide_react5 = require("lucide-react");
|
|
456
473
|
var import_react8 = require("react");
|
|
457
474
|
|
|
458
475
|
// src/lib/theme.ts
|
|
@@ -513,7 +530,7 @@ function Button({ className, variant, size, asChild = false, ...props }) {
|
|
|
513
530
|
}
|
|
514
531
|
|
|
515
532
|
// src/components/chat/ChatPanel.tsx
|
|
516
|
-
var
|
|
533
|
+
var import_lucide_react4 = require("lucide-react");
|
|
517
534
|
var import_react7 = require("react");
|
|
518
535
|
|
|
519
536
|
// src/components/ui/avatar.tsx
|
|
@@ -598,55 +615,184 @@ var Textarea = (0, import_react4.forwardRef)(
|
|
|
598
615
|
// src/components/chat/Composer.tsx
|
|
599
616
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
600
617
|
var MAX_ROWS_PX = 140;
|
|
601
|
-
function Composer({ onSend, onStop, busy, placeholder, disabled, autoFocus }) {
|
|
618
|
+
function Composer({ onSend, onStop, busy, placeholder, disabled, autoFocus, attachments, modelPicker }) {
|
|
602
619
|
const [value, setValue] = (0, import_react5.useState)("");
|
|
620
|
+
const [files, setFiles] = (0, import_react5.useState)([]);
|
|
621
|
+
const [fileError, setFileError] = (0, import_react5.useState)(void 0);
|
|
603
622
|
const textareaRef = (0, import_react5.useRef)(null);
|
|
623
|
+
const fileInputRef = (0, import_react5.useRef)(null);
|
|
624
|
+
const canAttach = Boolean(attachments?.enabled);
|
|
625
|
+
const models = modelPicker?.models ?? [];
|
|
604
626
|
(0, import_react5.useEffect)(() => {
|
|
605
627
|
const node = textareaRef.current;
|
|
606
628
|
if (!node) return;
|
|
607
629
|
node.style.height = "auto";
|
|
608
630
|
node.style.height = `${Math.min(node.scrollHeight, MAX_ROWS_PX)}px`;
|
|
609
631
|
}, [value]);
|
|
632
|
+
const addFiles = (0, import_react5.useCallback)(
|
|
633
|
+
async (list) => {
|
|
634
|
+
if (!list || !attachments) return;
|
|
635
|
+
setFileError(void 0);
|
|
636
|
+
const room = attachments.maxCount - files.length;
|
|
637
|
+
const chosen = Array.from(list).slice(0, Math.max(0, room));
|
|
638
|
+
if (Array.from(list).length > room) setFileError(`You can attach up to ${attachments.maxCount} file(s).`);
|
|
639
|
+
const next = [];
|
|
640
|
+
for (const file of chosen) {
|
|
641
|
+
if (!mimeAccepted(file.type || "application/octet-stream", attachments.accept)) {
|
|
642
|
+
setFileError(`Files of type ${file.type || "unknown"} aren't allowed.`);
|
|
643
|
+
continue;
|
|
644
|
+
}
|
|
645
|
+
if (file.size > attachments.maxMb * 1024 * 1024) {
|
|
646
|
+
setFileError(`Each file must be under ${attachments.maxMb} MB.`);
|
|
647
|
+
continue;
|
|
648
|
+
}
|
|
649
|
+
try {
|
|
650
|
+
next.push({
|
|
651
|
+
id: `${file.name}-${file.size}-${Math.random().toString(36).slice(2, 7)}`,
|
|
652
|
+
name: file.name,
|
|
653
|
+
mimeType: file.type || "application/octet-stream",
|
|
654
|
+
data: await readAsBase64(file)
|
|
655
|
+
});
|
|
656
|
+
} catch {
|
|
657
|
+
setFileError("Couldn't read that file.");
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
if (next.length) setFiles((current) => [...current, ...next]);
|
|
661
|
+
},
|
|
662
|
+
[attachments, files.length]
|
|
663
|
+
);
|
|
664
|
+
const removeFile = (id) => setFiles((current) => current.filter((file) => file.id !== id));
|
|
610
665
|
const submit = (0, import_react5.useCallback)(() => {
|
|
611
666
|
const text = value.trim();
|
|
612
|
-
if (!text || busy || disabled) return;
|
|
667
|
+
if (!text && files.length === 0 || busy || disabled) return;
|
|
613
668
|
setValue("");
|
|
614
|
-
|
|
615
|
-
|
|
669
|
+
const attached = files.map(({ name, mimeType, data }) => ({ name, mimeType, data }));
|
|
670
|
+
setFiles([]);
|
|
671
|
+
setFileError(void 0);
|
|
672
|
+
onSend(text, {
|
|
673
|
+
...attached.length ? { attachments: attached } : {},
|
|
674
|
+
...modelPicker?.value ? { model: modelPicker.value } : {}
|
|
675
|
+
});
|
|
676
|
+
}, [busy, disabled, files, modelPicker?.value, onSend, value]);
|
|
616
677
|
const onKeyDown = (event) => {
|
|
617
678
|
if (event.key === "Enter" && !event.shiftKey) {
|
|
618
679
|
event.preventDefault();
|
|
619
680
|
submit();
|
|
620
681
|
}
|
|
621
682
|
};
|
|
683
|
+
const nothingToSend = value.trim().length === 0 && files.length === 0;
|
|
622
684
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
623
685
|
"form",
|
|
624
686
|
{
|
|
625
|
-
className: "flex
|
|
687
|
+
className: "flex flex-col gap-2",
|
|
626
688
|
onSubmit: (event) => {
|
|
627
689
|
event.preventDefault();
|
|
628
690
|
submit();
|
|
629
691
|
},
|
|
630
692
|
children: [
|
|
631
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
632
|
-
|
|
693
|
+
files.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex flex-wrap gap-2", children: files.map((file) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
694
|
+
"span",
|
|
633
695
|
{
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
696
|
+
className: "inline-flex max-w-[14rem] items-center gap-1.5 rounded-[var(--frankie-radius)] border border-border bg-muted px-2 py-1 text-xs",
|
|
697
|
+
children: [
|
|
698
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react.Paperclip, { className: "size-3 shrink-0 opacity-70" }),
|
|
699
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "truncate", children: file.name }),
|
|
700
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
701
|
+
"button",
|
|
702
|
+
{
|
|
703
|
+
type: "button",
|
|
704
|
+
onClick: () => removeFile(file.id),
|
|
705
|
+
"aria-label": `Remove ${file.name}`,
|
|
706
|
+
className: "frankie-focus shrink-0 opacity-60 hover:opacity-100",
|
|
707
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react.X, { className: "size-3" })
|
|
708
|
+
}
|
|
709
|
+
)
|
|
710
|
+
]
|
|
711
|
+
},
|
|
712
|
+
file.id
|
|
713
|
+
)) }) : null,
|
|
714
|
+
fileError ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-xs text-red-600 dark:text-red-400", children: fileError }) : null,
|
|
715
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-end gap-2", children: [
|
|
716
|
+
canAttach ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
717
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
718
|
+
"input",
|
|
719
|
+
{
|
|
720
|
+
ref: fileInputRef,
|
|
721
|
+
type: "file",
|
|
722
|
+
multiple: true,
|
|
723
|
+
hidden: true,
|
|
724
|
+
accept: attachments?.accept.join(","),
|
|
725
|
+
onChange: (event) => {
|
|
726
|
+
void addFiles(event.target.files);
|
|
727
|
+
event.target.value = "";
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
),
|
|
731
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
732
|
+
Button,
|
|
733
|
+
{
|
|
734
|
+
type: "button",
|
|
735
|
+
size: "icon",
|
|
736
|
+
variant: "outline",
|
|
737
|
+
disabled: disabled || files.length >= (attachments?.maxCount ?? 0),
|
|
738
|
+
onClick: () => fileInputRef.current?.click(),
|
|
739
|
+
"aria-label": "Attach files",
|
|
740
|
+
title: "Attach files",
|
|
741
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react.Paperclip, {})
|
|
742
|
+
}
|
|
743
|
+
)
|
|
744
|
+
] }) : null,
|
|
745
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
746
|
+
Textarea,
|
|
747
|
+
{
|
|
748
|
+
ref: textareaRef,
|
|
749
|
+
rows: 1,
|
|
750
|
+
value,
|
|
751
|
+
disabled,
|
|
752
|
+
autoFocus,
|
|
753
|
+
onChange: (event) => setValue(event.target.value),
|
|
754
|
+
onKeyDown,
|
|
755
|
+
placeholder: placeholder ?? "Ask anything\u2026",
|
|
756
|
+
"aria-label": "Message"
|
|
757
|
+
}
|
|
758
|
+
),
|
|
759
|
+
models.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
760
|
+
"select",
|
|
761
|
+
{
|
|
762
|
+
value: modelPicker?.value ?? models[0]?.id,
|
|
763
|
+
onChange: (event) => modelPicker?.onChange(event.target.value),
|
|
764
|
+
disabled,
|
|
765
|
+
"aria-label": "Model",
|
|
766
|
+
className: "frankie-focus h-9 max-w-[8rem] rounded-[var(--frankie-radius)] border border-border bg-background px-2 text-sm",
|
|
767
|
+
children: models.map((model) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: model.id, children: model.label }, model.id))
|
|
768
|
+
}
|
|
769
|
+
) : null,
|
|
770
|
+
busy ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Button, { type: "button", size: "icon", variant: "outline", onClick: onStop, "aria-label": "Stop", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react.Square, {}) }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Button, { type: "submit", size: "icon", disabled: disabled || nothingToSend, "aria-label": "Send", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react.ArrowUp, {}) })
|
|
771
|
+
] })
|
|
646
772
|
]
|
|
647
773
|
}
|
|
648
774
|
);
|
|
649
775
|
}
|
|
776
|
+
function mimeAccepted(mimeType, accept) {
|
|
777
|
+
return accept.some(
|
|
778
|
+
(pattern) => pattern.endsWith("/*") ? mimeType.startsWith(pattern.slice(0, -1)) : pattern === mimeType
|
|
779
|
+
);
|
|
780
|
+
}
|
|
781
|
+
function readAsBase64(file) {
|
|
782
|
+
return new Promise((resolve, reject) => {
|
|
783
|
+
const reader = new FileReader();
|
|
784
|
+
reader.onload = () => {
|
|
785
|
+
const result = String(reader.result);
|
|
786
|
+
const comma = result.indexOf(",");
|
|
787
|
+
resolve(comma >= 0 ? result.slice(comma + 1) : result);
|
|
788
|
+
};
|
|
789
|
+
reader.onerror = () => reject(reader.error);
|
|
790
|
+
reader.readAsDataURL(file);
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// src/components/chat/MessageBubble.tsx
|
|
795
|
+
var import_lucide_react3 = require("lucide-react");
|
|
650
796
|
|
|
651
797
|
// src/components/chat/Markdown.tsx
|
|
652
798
|
var import_react6 = require("react");
|
|
@@ -819,7 +965,20 @@ function MessageBubble({
|
|
|
819
965
|
renderTool
|
|
820
966
|
}) {
|
|
821
967
|
if (message.role === "user") {
|
|
822
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.
|
|
968
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col items-end gap-1", children: [
|
|
969
|
+
message.attachments?.length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex max-w-[85%] flex-wrap justify-end gap-1", children: message.attachments.map((file, index) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
970
|
+
"span",
|
|
971
|
+
{
|
|
972
|
+
className: "inline-flex max-w-[12rem] items-center gap-1 rounded-[var(--frankie-radius)] border border-border bg-muted px-2 py-1 text-xs",
|
|
973
|
+
children: [
|
|
974
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.Paperclip, { className: "size-3 shrink-0 opacity-70" }),
|
|
975
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "truncate", children: file.name })
|
|
976
|
+
]
|
|
977
|
+
},
|
|
978
|
+
`${file.name}-${index}`
|
|
979
|
+
)) }) : null,
|
|
980
|
+
message.text ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "max-w-[85%] rounded-[var(--frankie-radius)] bg-primary px-3 py-2 text-sm text-primary-foreground", children: message.text }) : null
|
|
981
|
+
] });
|
|
823
982
|
}
|
|
824
983
|
const empty = message.text.length === 0 && message.tools.length === 0;
|
|
825
984
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex gap-2", children: [
|
|
@@ -881,6 +1040,9 @@ function ChatPanel({
|
|
|
881
1040
|
const theme = useFrankieTheme();
|
|
882
1041
|
const { messages, busy, error, send, stop, reset } = useFrankieChat();
|
|
883
1042
|
const scrollRef = (0, import_react7.useRef)(null);
|
|
1043
|
+
const features = config?.features;
|
|
1044
|
+
const pickerModels = features?.modelPicker.enabled ? features.modelPicker.models : [];
|
|
1045
|
+
const [model, setModel] = (0, import_react7.useState)(void 0);
|
|
884
1046
|
(0, import_react7.useEffect)(() => {
|
|
885
1047
|
const node = scrollRef.current;
|
|
886
1048
|
if (!node) return;
|
|
@@ -907,8 +1069,8 @@ function ChatPanel({
|
|
|
907
1069
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardTitle, { children: name }),
|
|
908
1070
|
config?.branding.tagline ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardDescription, { children: config.branding.tagline }) : null
|
|
909
1071
|
] }),
|
|
910
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { size: "icon", variant: "ghost", onClick: reset, "aria-label": "Start a new conversation", title: "New conversation", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
911
|
-
onClose ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { size: "icon", variant: "ghost", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1072
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { size: "icon", variant: "ghost", onClick: reset, "aria-label": "Start a new conversation", title: "New conversation", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.RotateCcw, {}) }),
|
|
1073
|
+
onClose ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { size: "icon", variant: "ghost", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.X, {}) }) : null
|
|
912
1074
|
] }),
|
|
913
1075
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardContent, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ScrollArea, { ref: scrollRef, className: "flex h-full flex-col gap-4 p-4", "aria-live": "polite", children: configError ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-sm text-muted-foreground", children: configError }) : loading ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-sm text-muted-foreground", children: "Loading\u2026" }) : messages.length === 0 ? emptyState ?? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-4", children: [
|
|
914
1076
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-sm text-muted-foreground", children: config?.greeting }),
|
|
@@ -936,7 +1098,9 @@ function ChatPanel({
|
|
|
936
1098
|
busy,
|
|
937
1099
|
disabled: Boolean(configError),
|
|
938
1100
|
...placeholder ? { placeholder } : {},
|
|
939
|
-
...autoFocus ? { autoFocus } : {}
|
|
1101
|
+
...autoFocus ? { autoFocus } : {},
|
|
1102
|
+
...features?.attachments.enabled ? { attachments: features.attachments } : {},
|
|
1103
|
+
...pickerModels.length ? { modelPicker: { models: pickerModels, value: model ?? pickerModels[0]?.id, onChange: setModel } } : {}
|
|
940
1104
|
}
|
|
941
1105
|
) }),
|
|
942
1106
|
footer
|
|
@@ -993,7 +1157,7 @@ function FrankieWidget({
|
|
|
993
1157
|
"aria-expanded": open,
|
|
994
1158
|
"aria-label": open ? "Close the assistant" : label,
|
|
995
1159
|
title: label,
|
|
996
|
-
children: open ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1160
|
+
children: open ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react5.X, { className: "size-5" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react5.MessageCircle, { className: "size-5" })
|
|
997
1161
|
}
|
|
998
1162
|
)
|
|
999
1163
|
] })
|