@blank-utils/llm 0.2.3 → 0.2.7
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/README.md +134 -4
- package/dist/index.js +755 -293
- package/dist/react/chat-input.d.ts +23 -2
- package/dist/react/chat-input.d.ts.map +1 -1
- package/dist/react/components.d.ts +24 -12
- package/dist/react/components.d.ts.map +1 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +778 -293
- package/package.json +6 -3
package/dist/index.js
CHANGED
|
@@ -57129,23 +57129,23 @@ async function isWebGPUSupported() {
|
|
|
57129
57129
|
import {
|
|
57130
57130
|
createContext,
|
|
57131
57131
|
useContext,
|
|
57132
|
-
useState as
|
|
57132
|
+
useState as useState3,
|
|
57133
57133
|
useCallback as useCallback2,
|
|
57134
57134
|
useEffect as useEffect3,
|
|
57135
|
-
useMemo,
|
|
57135
|
+
useMemo as useMemo2,
|
|
57136
57136
|
useRef as useRef3
|
|
57137
57137
|
} from "react";
|
|
57138
57138
|
|
|
57139
57139
|
// src/react/components.tsx
|
|
57140
|
-
import { useRef as useRef2, useEffect as useEffect2, useState } from "react";
|
|
57140
|
+
import { useRef as useRef2, useEffect as useEffect2, useState as useState2, useMemo } from "react";
|
|
57141
57141
|
|
|
57142
57142
|
// src/react/chat-input.tsx
|
|
57143
|
-
import { useRef, useEffect, useCallback } from "react";
|
|
57144
|
-
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
57143
|
+
import { useRef, useEffect, useCallback, useState } from "react";
|
|
57144
|
+
import { jsxDEV, Fragment } from "react/jsx-dev-runtime";
|
|
57145
57145
|
function SendIcon() {
|
|
57146
57146
|
return /* @__PURE__ */ jsxDEV("svg", {
|
|
57147
|
-
width: "
|
|
57148
|
-
height: "
|
|
57147
|
+
width: "14",
|
|
57148
|
+
height: "14",
|
|
57149
57149
|
viewBox: "0 0 24 24",
|
|
57150
57150
|
fill: "none",
|
|
57151
57151
|
stroke: "currentColor",
|
|
@@ -57153,30 +57153,88 @@ function SendIcon() {
|
|
|
57153
57153
|
strokeLinecap: "round",
|
|
57154
57154
|
strokeLinejoin: "round",
|
|
57155
57155
|
children: [
|
|
57156
|
-
/* @__PURE__ */ jsxDEV("
|
|
57157
|
-
|
|
57156
|
+
/* @__PURE__ */ jsxDEV("line", {
|
|
57157
|
+
x1: "5",
|
|
57158
|
+
y1: "12",
|
|
57159
|
+
x2: "19",
|
|
57160
|
+
y2: "12"
|
|
57158
57161
|
}, undefined, false, undefined, this),
|
|
57159
|
-
/* @__PURE__ */ jsxDEV("
|
|
57160
|
-
|
|
57162
|
+
/* @__PURE__ */ jsxDEV("polyline", {
|
|
57163
|
+
points: "12 5 19 12 12 19"
|
|
57161
57164
|
}, undefined, false, undefined, this)
|
|
57162
57165
|
]
|
|
57163
57166
|
}, undefined, true, undefined, this);
|
|
57164
57167
|
}
|
|
57165
57168
|
function StopIcon() {
|
|
57166
57169
|
return /* @__PURE__ */ jsxDEV("svg", {
|
|
57167
|
-
width: "
|
|
57168
|
-
height: "
|
|
57170
|
+
width: "14",
|
|
57171
|
+
height: "14",
|
|
57169
57172
|
viewBox: "0 0 24 24",
|
|
57170
57173
|
fill: "currentColor",
|
|
57171
57174
|
children: /* @__PURE__ */ jsxDEV("rect", {
|
|
57172
|
-
x: "
|
|
57173
|
-
y: "
|
|
57174
|
-
width: "
|
|
57175
|
-
height: "
|
|
57176
|
-
rx: "2"
|
|
57175
|
+
x: "6",
|
|
57176
|
+
y: "6",
|
|
57177
|
+
width: "12",
|
|
57178
|
+
height: "12"
|
|
57177
57179
|
}, undefined, false, undefined, this)
|
|
57178
57180
|
}, undefined, false, undefined, this);
|
|
57179
57181
|
}
|
|
57182
|
+
function ImageIcon() {
|
|
57183
|
+
return /* @__PURE__ */ jsxDEV("svg", {
|
|
57184
|
+
width: "14",
|
|
57185
|
+
height: "14",
|
|
57186
|
+
viewBox: "0 0 24 24",
|
|
57187
|
+
fill: "none",
|
|
57188
|
+
stroke: "currentColor",
|
|
57189
|
+
strokeWidth: "2",
|
|
57190
|
+
strokeLinecap: "round",
|
|
57191
|
+
strokeLinejoin: "round",
|
|
57192
|
+
children: [
|
|
57193
|
+
/* @__PURE__ */ jsxDEV("rect", {
|
|
57194
|
+
x: "3",
|
|
57195
|
+
y: "3",
|
|
57196
|
+
width: "18",
|
|
57197
|
+
height: "18",
|
|
57198
|
+
rx: "0",
|
|
57199
|
+
ry: "0"
|
|
57200
|
+
}, undefined, false, undefined, this),
|
|
57201
|
+
/* @__PURE__ */ jsxDEV("circle", {
|
|
57202
|
+
cx: "8.5",
|
|
57203
|
+
cy: "8.5",
|
|
57204
|
+
r: "1.5"
|
|
57205
|
+
}, undefined, false, undefined, this),
|
|
57206
|
+
/* @__PURE__ */ jsxDEV("polyline", {
|
|
57207
|
+
points: "21 15 16 10 5 21"
|
|
57208
|
+
}, undefined, false, undefined, this)
|
|
57209
|
+
]
|
|
57210
|
+
}, undefined, true, undefined, this);
|
|
57211
|
+
}
|
|
57212
|
+
function XIcon() {
|
|
57213
|
+
return /* @__PURE__ */ jsxDEV("svg", {
|
|
57214
|
+
width: "10",
|
|
57215
|
+
height: "10",
|
|
57216
|
+
viewBox: "0 0 24 24",
|
|
57217
|
+
fill: "none",
|
|
57218
|
+
stroke: "currentColor",
|
|
57219
|
+
strokeWidth: "3",
|
|
57220
|
+
strokeLinecap: "round",
|
|
57221
|
+
strokeLinejoin: "round",
|
|
57222
|
+
children: [
|
|
57223
|
+
/* @__PURE__ */ jsxDEV("line", {
|
|
57224
|
+
x1: "18",
|
|
57225
|
+
y1: "6",
|
|
57226
|
+
x2: "6",
|
|
57227
|
+
y2: "18"
|
|
57228
|
+
}, undefined, false, undefined, this),
|
|
57229
|
+
/* @__PURE__ */ jsxDEV("line", {
|
|
57230
|
+
x1: "6",
|
|
57231
|
+
y1: "6",
|
|
57232
|
+
x2: "18",
|
|
57233
|
+
y2: "18"
|
|
57234
|
+
}, undefined, false, undefined, this)
|
|
57235
|
+
]
|
|
57236
|
+
}, undefined, true, undefined, this);
|
|
57237
|
+
}
|
|
57180
57238
|
var STYLE_ID = "__llm-chat-input-styles";
|
|
57181
57239
|
function injectStyles(theme) {
|
|
57182
57240
|
if (typeof document === "undefined")
|
|
@@ -57184,82 +57242,192 @@ function injectStyles(theme) {
|
|
|
57184
57242
|
const existing = document.getElementById(STYLE_ID);
|
|
57185
57243
|
if (existing)
|
|
57186
57244
|
existing.remove();
|
|
57187
|
-
const
|
|
57245
|
+
const d = theme === "dark";
|
|
57246
|
+
const border = d ? "rgba(255,255,255,0.12)" : "rgba(0,0,0,0.12)";
|
|
57247
|
+
const borderFocus = d ? "rgba(255,255,255,0.35)" : "rgba(0,0,0,0.35)";
|
|
57248
|
+
const bg2 = d ? "#000000" : "#ffffff";
|
|
57249
|
+
const text = d ? "#ffffff" : "#000000";
|
|
57250
|
+
const textMuted = d ? "rgba(255,255,255,0.3)" : "rgba(0,0,0,0.3)";
|
|
57251
|
+
const textSecondary = d ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)";
|
|
57252
|
+
const monoFont = `ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, monospace`;
|
|
57253
|
+
const sansFont = `-apple-system, BlinkMacSystemFont, "Segoe UI", "Inter", Roboto, Helvetica, Arial, sans-serif`;
|
|
57188
57254
|
const css = `
|
|
57189
57255
|
.llm-ci {
|
|
57190
57256
|
display: flex;
|
|
57191
57257
|
flex-direction: column;
|
|
57192
|
-
border
|
|
57193
|
-
|
|
57194
|
-
|
|
57195
|
-
|
|
57196
|
-
transition: border-color 0.2s, box-shadow 0.2s;
|
|
57258
|
+
border: 1px solid ${border};
|
|
57259
|
+
background: ${bg2};
|
|
57260
|
+
padding: 12px;
|
|
57261
|
+
transition: border-color 0.15s;
|
|
57197
57262
|
position: relative;
|
|
57198
57263
|
}
|
|
57199
57264
|
.llm-ci:focus-within {
|
|
57200
|
-
border-color: ${
|
|
57201
|
-
box-shadow: 0 0 0 2px ${isDark ? "rgba(56,189,248,0.1)" : "rgba(59,130,246,0.1)"};
|
|
57265
|
+
border-color: ${borderFocus};
|
|
57202
57266
|
}
|
|
57267
|
+
|
|
57268
|
+
/* Attached Images */
|
|
57269
|
+
.llm-ci-images {
|
|
57270
|
+
display: flex;
|
|
57271
|
+
flex-wrap: wrap;
|
|
57272
|
+
gap: 6px;
|
|
57273
|
+
margin-bottom: 8px;
|
|
57274
|
+
}
|
|
57275
|
+
.llm-ci-image-preview {
|
|
57276
|
+
position: relative;
|
|
57277
|
+
width: 52px;
|
|
57278
|
+
height: 52px;
|
|
57279
|
+
overflow: hidden;
|
|
57280
|
+
border: 1px solid ${border};
|
|
57281
|
+
}
|
|
57282
|
+
.llm-ci-image-preview img {
|
|
57283
|
+
width: 100%;
|
|
57284
|
+
height: 100%;
|
|
57285
|
+
object-fit: cover;
|
|
57286
|
+
}
|
|
57287
|
+
.llm-ci-image-remove {
|
|
57288
|
+
position: absolute;
|
|
57289
|
+
top: 2px;
|
|
57290
|
+
right: 2px;
|
|
57291
|
+
width: 16px;
|
|
57292
|
+
height: 16px;
|
|
57293
|
+
background: ${d ? "rgba(0,0,0,0.7)" : "rgba(255,255,255,0.8)"};
|
|
57294
|
+
color: ${text};
|
|
57295
|
+
border: none;
|
|
57296
|
+
display: flex;
|
|
57297
|
+
align-items: center;
|
|
57298
|
+
justify-content: center;
|
|
57299
|
+
cursor: pointer;
|
|
57300
|
+
opacity: 0;
|
|
57301
|
+
transition: opacity 0.1s;
|
|
57302
|
+
}
|
|
57303
|
+
.llm-ci-image-preview:hover .llm-ci-image-remove {
|
|
57304
|
+
opacity: 1;
|
|
57305
|
+
}
|
|
57306
|
+
|
|
57307
|
+
/* Textarea */
|
|
57203
57308
|
.llm-ci textarea {
|
|
57204
57309
|
width: 100%;
|
|
57205
|
-
min-height:
|
|
57206
|
-
max-height:
|
|
57310
|
+
min-height: 24px;
|
|
57311
|
+
max-height: 200px;
|
|
57207
57312
|
resize: none;
|
|
57208
57313
|
border: none;
|
|
57209
57314
|
outline: none;
|
|
57210
57315
|
background: transparent;
|
|
57211
|
-
color: ${
|
|
57316
|
+
color: ${text};
|
|
57212
57317
|
font-size: 14px;
|
|
57213
57318
|
line-height: 1.5;
|
|
57214
|
-
padding:
|
|
57215
|
-
|
|
57319
|
+
padding: 0;
|
|
57320
|
+
margin: 0;
|
|
57321
|
+
font-family: ${sansFont};
|
|
57216
57322
|
scrollbar-width: thin;
|
|
57217
57323
|
}
|
|
57218
57324
|
.llm-ci textarea::placeholder {
|
|
57219
|
-
color: ${
|
|
57325
|
+
color: ${textMuted};
|
|
57220
57326
|
}
|
|
57327
|
+
|
|
57328
|
+
/* Toolbar */
|
|
57221
57329
|
.llm-ci-toolbar {
|
|
57222
57330
|
display: flex;
|
|
57223
57331
|
align-items: center;
|
|
57224
57332
|
justify-content: space-between;
|
|
57225
|
-
|
|
57333
|
+
margin-top: 8px;
|
|
57334
|
+
min-height: 28px;
|
|
57226
57335
|
}
|
|
57227
|
-
.llm-ci-actions {
|
|
57336
|
+
.llm-ci-left-actions {
|
|
57228
57337
|
display: flex;
|
|
57229
57338
|
align-items: center;
|
|
57230
57339
|
gap: 2px;
|
|
57231
57340
|
}
|
|
57232
|
-
.llm-ci-
|
|
57341
|
+
.llm-ci-right-actions {
|
|
57342
|
+
display: flex;
|
|
57343
|
+
align-items: center;
|
|
57344
|
+
gap: 8px;
|
|
57345
|
+
}
|
|
57346
|
+
|
|
57347
|
+
/* Icon Buttons */
|
|
57348
|
+
.llm-ci-btn-icon {
|
|
57233
57349
|
display: flex;
|
|
57234
57350
|
align-items: center;
|
|
57235
57351
|
justify-content: center;
|
|
57236
|
-
width:
|
|
57237
|
-
height:
|
|
57238
|
-
border-radius: 50%;
|
|
57352
|
+
width: 28px;
|
|
57353
|
+
height: 28px;
|
|
57239
57354
|
border: none;
|
|
57355
|
+
background: transparent;
|
|
57356
|
+
color: ${textSecondary};
|
|
57240
57357
|
cursor: pointer;
|
|
57241
|
-
transition:
|
|
57242
|
-
|
|
57358
|
+
transition: color 0.1s;
|
|
57359
|
+
}
|
|
57360
|
+
.llm-ci-btn-icon:hover {
|
|
57361
|
+
color: ${text};
|
|
57362
|
+
}
|
|
57363
|
+
|
|
57364
|
+
/* Send / Stop — flat, monospace, uppercase */
|
|
57365
|
+
.llm-ci-send {
|
|
57366
|
+
display: flex;
|
|
57367
|
+
align-items: center;
|
|
57368
|
+
justify-content: center;
|
|
57369
|
+
height: 28px;
|
|
57370
|
+
padding: 0 12px;
|
|
57371
|
+
border: 1px solid ${border};
|
|
57372
|
+
font-size: 10px;
|
|
57373
|
+
font-weight: 400;
|
|
57374
|
+
font-family: ${monoFont};
|
|
57375
|
+
text-transform: uppercase;
|
|
57376
|
+
letter-spacing: 0.08em;
|
|
57377
|
+
cursor: pointer;
|
|
57378
|
+
transition: all 0.1s;
|
|
57379
|
+
gap: 6px;
|
|
57380
|
+
background: transparent;
|
|
57381
|
+
color: ${textSecondary};
|
|
57243
57382
|
}
|
|
57244
57383
|
.llm-ci-send--active {
|
|
57245
|
-
background: ${
|
|
57246
|
-
color:
|
|
57384
|
+
background: ${text};
|
|
57385
|
+
color: ${bg2};
|
|
57386
|
+
border-color: ${text};
|
|
57247
57387
|
}
|
|
57248
57388
|
.llm-ci-send--active:hover {
|
|
57249
|
-
|
|
57250
|
-
transform: scale(1.05);
|
|
57389
|
+
opacity: 0.8;
|
|
57251
57390
|
}
|
|
57252
57391
|
.llm-ci-send--disabled {
|
|
57253
|
-
|
|
57254
|
-
color: ${
|
|
57392
|
+
color: ${textMuted};
|
|
57393
|
+
border-color: ${d ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.06)"};
|
|
57255
57394
|
cursor: not-allowed;
|
|
57256
57395
|
}
|
|
57257
57396
|
.llm-ci-send--stop {
|
|
57258
|
-
background:
|
|
57259
|
-
color: ${
|
|
57397
|
+
background: transparent;
|
|
57398
|
+
border-color: ${border};
|
|
57399
|
+
color: ${textSecondary};
|
|
57260
57400
|
}
|
|
57261
57401
|
.llm-ci-send--stop:hover {
|
|
57262
|
-
|
|
57402
|
+
border-color: ${borderFocus};
|
|
57403
|
+
color: ${text};
|
|
57404
|
+
}
|
|
57405
|
+
|
|
57406
|
+
/* Model Selector Slot */
|
|
57407
|
+
.llm-ci-model-selector {
|
|
57408
|
+
margin-right: auto;
|
|
57409
|
+
}
|
|
57410
|
+
|
|
57411
|
+
/* Hidden file input */
|
|
57412
|
+
.llm-ci-file-input {
|
|
57413
|
+
display: none;
|
|
57414
|
+
}
|
|
57415
|
+
|
|
57416
|
+
/* Drag Overlay */
|
|
57417
|
+
.llm-ci-drag-overlay {
|
|
57418
|
+
position: absolute;
|
|
57419
|
+
inset: 0;
|
|
57420
|
+
background: ${d ? "rgba(0,0,0,0.9)" : "rgba(255,255,255,0.9)"};
|
|
57421
|
+
display: flex;
|
|
57422
|
+
align-items: center;
|
|
57423
|
+
justify-content: center;
|
|
57424
|
+
z-index: 10;
|
|
57425
|
+
border: 1px dashed ${textSecondary};
|
|
57426
|
+
color: ${textSecondary};
|
|
57427
|
+
font-size: 11px;
|
|
57428
|
+
font-family: ${monoFont};
|
|
57429
|
+
text-transform: uppercase;
|
|
57430
|
+
letter-spacing: 0.08em;
|
|
57263
57431
|
}
|
|
57264
57432
|
`;
|
|
57265
57433
|
const style = document.createElement("style");
|
|
@@ -57275,12 +57443,18 @@ function ChatInput({
|
|
|
57275
57443
|
disabled = false,
|
|
57276
57444
|
isGenerating = false,
|
|
57277
57445
|
placeholder = "Type a message...",
|
|
57278
|
-
maxRows =
|
|
57446
|
+
maxRows = 8,
|
|
57279
57447
|
actions,
|
|
57280
57448
|
theme = "dark",
|
|
57281
|
-
className
|
|
57449
|
+
className,
|
|
57450
|
+
images = [],
|
|
57451
|
+
onImageAdd,
|
|
57452
|
+
onImageRemove,
|
|
57453
|
+
modelSelector
|
|
57282
57454
|
}) {
|
|
57283
57455
|
const textareaRef = useRef(null);
|
|
57456
|
+
const fileInputRef = useRef(null);
|
|
57457
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
57284
57458
|
useEffect(() => {
|
|
57285
57459
|
injectStyles(theme);
|
|
57286
57460
|
}, [theme]);
|
|
@@ -57290,19 +57464,68 @@ function ChatInput({
|
|
|
57290
57464
|
return;
|
|
57291
57465
|
textarea.style.height = "auto";
|
|
57292
57466
|
const lineHeight = 21;
|
|
57293
|
-
const maxHeight = lineHeight * maxRows +
|
|
57467
|
+
const maxHeight = lineHeight * maxRows + 24;
|
|
57294
57468
|
const newHeight = Math.min(textarea.scrollHeight, maxHeight);
|
|
57295
57469
|
textarea.style.height = `${newHeight}px`;
|
|
57296
57470
|
}, [value, maxRows]);
|
|
57297
57471
|
const handleKeyDown = useCallback((e) => {
|
|
57298
57472
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
57299
57473
|
e.preventDefault();
|
|
57300
|
-
if (!disabled && value.trim()) {
|
|
57474
|
+
if (!disabled && (value.trim() || images.length > 0)) {
|
|
57301
57475
|
onSend();
|
|
57302
57476
|
}
|
|
57303
57477
|
}
|
|
57304
|
-
}, [disabled, value, onSend]);
|
|
57305
|
-
const
|
|
57478
|
+
}, [disabled, value, images.length, onSend]);
|
|
57479
|
+
const processFile = useCallback((file) => {
|
|
57480
|
+
if (!file.type.startsWith("image/"))
|
|
57481
|
+
return;
|
|
57482
|
+
const reader = new FileReader;
|
|
57483
|
+
reader.onload = (e) => {
|
|
57484
|
+
if (e.target?.result && typeof e.target.result === "string") {
|
|
57485
|
+
const id2 = Math.random().toString(36).substring(7);
|
|
57486
|
+
onImageAdd?.({
|
|
57487
|
+
id: id2,
|
|
57488
|
+
dataUrl: e.target.result,
|
|
57489
|
+
file,
|
|
57490
|
+
name: file.name
|
|
57491
|
+
});
|
|
57492
|
+
}
|
|
57493
|
+
};
|
|
57494
|
+
reader.readAsDataURL(file);
|
|
57495
|
+
}, [onImageAdd]);
|
|
57496
|
+
const handlePaste = useCallback((e) => {
|
|
57497
|
+
const items = e.clipboardData.items;
|
|
57498
|
+
for (let i = 0;i < items.length; i++) {
|
|
57499
|
+
const item = items[i];
|
|
57500
|
+
if (item && item.type.indexOf("image") !== -1) {
|
|
57501
|
+
const file = item.getAsFile();
|
|
57502
|
+
if (file)
|
|
57503
|
+
processFile(file);
|
|
57504
|
+
}
|
|
57505
|
+
}
|
|
57506
|
+
}, [processFile]);
|
|
57507
|
+
const handleDrop = useCallback((e) => {
|
|
57508
|
+
e.preventDefault();
|
|
57509
|
+
setIsDragging(false);
|
|
57510
|
+
const files = e.dataTransfer.files;
|
|
57511
|
+
for (let i = 0;i < files.length; i++) {
|
|
57512
|
+
const file = files.item(i);
|
|
57513
|
+
if (file)
|
|
57514
|
+
processFile(file);
|
|
57515
|
+
}
|
|
57516
|
+
}, [processFile]);
|
|
57517
|
+
const handleFileSelect = useCallback((e) => {
|
|
57518
|
+
const files = e.target.files;
|
|
57519
|
+
if (!files)
|
|
57520
|
+
return;
|
|
57521
|
+
for (let i = 0;i < files.length; i++) {
|
|
57522
|
+
const file = files.item(i);
|
|
57523
|
+
if (file)
|
|
57524
|
+
processFile(file);
|
|
57525
|
+
}
|
|
57526
|
+
e.target.value = "";
|
|
57527
|
+
}, [processFile]);
|
|
57528
|
+
const hasValue = value.trim().length > 0 || images.length > 0;
|
|
57306
57529
|
const canSend = hasValue && !disabled && !isGenerating;
|
|
57307
57530
|
let sendClass = "llm-ci-send";
|
|
57308
57531
|
if (isGenerating) {
|
|
@@ -57314,12 +57537,49 @@ function ChatInput({
|
|
|
57314
57537
|
}
|
|
57315
57538
|
return /* @__PURE__ */ jsxDEV("div", {
|
|
57316
57539
|
className: `llm-ci${className ? ` ${className}` : ""}`,
|
|
57540
|
+
onDragOver: (e) => {
|
|
57541
|
+
e.preventDefault();
|
|
57542
|
+
setIsDragging(true);
|
|
57543
|
+
},
|
|
57544
|
+
onDragLeave: () => setIsDragging(false),
|
|
57545
|
+
onDrop: handleDrop,
|
|
57317
57546
|
children: [
|
|
57547
|
+
isDragging && /* @__PURE__ */ jsxDEV("div", {
|
|
57548
|
+
className: "llm-ci-drag-overlay",
|
|
57549
|
+
children: "[Drop image to attach]"
|
|
57550
|
+
}, undefined, false, undefined, this),
|
|
57551
|
+
/* @__PURE__ */ jsxDEV("input", {
|
|
57552
|
+
ref: fileInputRef,
|
|
57553
|
+
type: "file",
|
|
57554
|
+
accept: "image/*",
|
|
57555
|
+
multiple: true,
|
|
57556
|
+
className: "llm-ci-file-input",
|
|
57557
|
+
onChange: handleFileSelect
|
|
57558
|
+
}, undefined, false, undefined, this),
|
|
57559
|
+
images.length > 0 && /* @__PURE__ */ jsxDEV("div", {
|
|
57560
|
+
className: "llm-ci-images",
|
|
57561
|
+
children: images.map((img) => /* @__PURE__ */ jsxDEV("div", {
|
|
57562
|
+
className: "llm-ci-image-preview",
|
|
57563
|
+
children: [
|
|
57564
|
+
/* @__PURE__ */ jsxDEV("img", {
|
|
57565
|
+
src: img.dataUrl,
|
|
57566
|
+
alt: "attachment"
|
|
57567
|
+
}, undefined, false, undefined, this),
|
|
57568
|
+
/* @__PURE__ */ jsxDEV("button", {
|
|
57569
|
+
type: "button",
|
|
57570
|
+
className: "llm-ci-image-remove",
|
|
57571
|
+
onClick: () => onImageRemove?.(img.id),
|
|
57572
|
+
children: /* @__PURE__ */ jsxDEV(XIcon, {}, undefined, false, undefined, this)
|
|
57573
|
+
}, undefined, false, undefined, this)
|
|
57574
|
+
]
|
|
57575
|
+
}, img.id, true, undefined, this))
|
|
57576
|
+
}, undefined, false, undefined, this),
|
|
57318
57577
|
/* @__PURE__ */ jsxDEV("textarea", {
|
|
57319
57578
|
ref: textareaRef,
|
|
57320
57579
|
value,
|
|
57321
57580
|
onChange: (e) => onChange(e.target.value),
|
|
57322
57581
|
onKeyDown: handleKeyDown,
|
|
57582
|
+
onPaste: handlePaste,
|
|
57323
57583
|
placeholder,
|
|
57324
57584
|
disabled: disabled && !isGenerating,
|
|
57325
57585
|
rows: 1
|
|
@@ -57328,16 +57588,42 @@ function ChatInput({
|
|
|
57328
57588
|
className: "llm-ci-toolbar",
|
|
57329
57589
|
children: [
|
|
57330
57590
|
/* @__PURE__ */ jsxDEV("div", {
|
|
57331
|
-
className: "llm-ci-actions",
|
|
57332
|
-
children:
|
|
57333
|
-
|
|
57334
|
-
|
|
57335
|
-
|
|
57336
|
-
|
|
57337
|
-
|
|
57338
|
-
|
|
57339
|
-
|
|
57340
|
-
|
|
57591
|
+
className: "llm-ci-left-actions",
|
|
57592
|
+
children: [
|
|
57593
|
+
modelSelector && /* @__PURE__ */ jsxDEV("div", {
|
|
57594
|
+
className: "llm-ci-model-selector",
|
|
57595
|
+
children: modelSelector
|
|
57596
|
+
}, undefined, false, undefined, this),
|
|
57597
|
+
/* @__PURE__ */ jsxDEV("button", {
|
|
57598
|
+
type: "button",
|
|
57599
|
+
className: "llm-ci-btn-icon",
|
|
57600
|
+
onClick: () => fileInputRef.current?.click(),
|
|
57601
|
+
title: "Attach image (or Ctrl+V to paste)",
|
|
57602
|
+
children: /* @__PURE__ */ jsxDEV(ImageIcon, {}, undefined, false, undefined, this)
|
|
57603
|
+
}, undefined, false, undefined, this),
|
|
57604
|
+
actions
|
|
57605
|
+
]
|
|
57606
|
+
}, undefined, true, undefined, this),
|
|
57607
|
+
/* @__PURE__ */ jsxDEV("div", {
|
|
57608
|
+
className: "llm-ci-right-actions",
|
|
57609
|
+
children: /* @__PURE__ */ jsxDEV("button", {
|
|
57610
|
+
type: "button",
|
|
57611
|
+
className: sendClass,
|
|
57612
|
+
onClick: isGenerating ? onStop : onSend,
|
|
57613
|
+
disabled: !isGenerating && !canSend,
|
|
57614
|
+
"aria-label": isGenerating ? "Stop generation" : "Send message",
|
|
57615
|
+
children: isGenerating ? /* @__PURE__ */ jsxDEV(Fragment, {
|
|
57616
|
+
children: [
|
|
57617
|
+
/* @__PURE__ */ jsxDEV(StopIcon, {}, undefined, false, undefined, this),
|
|
57618
|
+
" Stop"
|
|
57619
|
+
]
|
|
57620
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV(Fragment, {
|
|
57621
|
+
children: [
|
|
57622
|
+
"Send ",
|
|
57623
|
+
/* @__PURE__ */ jsxDEV(SendIcon, {}, undefined, false, undefined, this)
|
|
57624
|
+
]
|
|
57625
|
+
}, undefined, true, undefined, this)
|
|
57626
|
+
}, undefined, false, undefined, this)
|
|
57341
57627
|
}, undefined, false, undefined, this)
|
|
57342
57628
|
]
|
|
57343
57629
|
}, undefined, true, undefined, this)
|
|
@@ -57346,7 +57632,16 @@ function ChatInput({
|
|
|
57346
57632
|
}
|
|
57347
57633
|
|
|
57348
57634
|
// src/react/components.tsx
|
|
57349
|
-
import {
|
|
57635
|
+
import { Streamdown } from "streamdown";
|
|
57636
|
+
import { code } from "@streamdown/code";
|
|
57637
|
+
import { mermaid } from "@streamdown/mermaid";
|
|
57638
|
+
import { jsxDEV as jsxDEV2, Fragment as Fragment2 } from "react/jsx-dev-runtime";
|
|
57639
|
+
var DEFAULT_SYSTEM_PROMPT = `You are a helpful AI assistant.
|
|
57640
|
+
- You can use full Markdown (bold, italic, headers, lists).
|
|
57641
|
+
- You can use Code Blocks with language syntax highlighting.
|
|
57642
|
+
- You can use Mermaid diagrams (\`\`\`mermaid ... \`\`\`).
|
|
57643
|
+
- You can use LaTeX math ($$ ... $$).`;
|
|
57644
|
+
var ALL_MODELS = { ...WEBLLM_MODELS, ...TRANSFORMERS_MODELS };
|
|
57350
57645
|
function RetryIcon() {
|
|
57351
57646
|
return /* @__PURE__ */ jsxDEV2("svg", {
|
|
57352
57647
|
width: "14",
|
|
@@ -57367,6 +57662,21 @@ function RetryIcon() {
|
|
|
57367
57662
|
]
|
|
57368
57663
|
}, undefined, true, undefined, this);
|
|
57369
57664
|
}
|
|
57665
|
+
function ChevronDownIcon() {
|
|
57666
|
+
return /* @__PURE__ */ jsxDEV2("svg", {
|
|
57667
|
+
width: "12",
|
|
57668
|
+
height: "12",
|
|
57669
|
+
viewBox: "0 0 24 24",
|
|
57670
|
+
fill: "none",
|
|
57671
|
+
stroke: "currentColor",
|
|
57672
|
+
strokeWidth: "2",
|
|
57673
|
+
strokeLinecap: "round",
|
|
57674
|
+
strokeLinejoin: "round",
|
|
57675
|
+
children: /* @__PURE__ */ jsxDEV2("polyline", {
|
|
57676
|
+
points: "6 9 12 15 18 9"
|
|
57677
|
+
}, undefined, false, undefined, this)
|
|
57678
|
+
}, undefined, false, undefined, this);
|
|
57679
|
+
}
|
|
57370
57680
|
var STYLE_ID2 = "__llm-chat-styles";
|
|
57371
57681
|
function injectChatStyles(theme) {
|
|
57372
57682
|
if (typeof document === "undefined")
|
|
@@ -57375,16 +57685,24 @@ function injectChatStyles(theme) {
|
|
|
57375
57685
|
if (existing)
|
|
57376
57686
|
existing.remove();
|
|
57377
57687
|
const d = theme === "dark";
|
|
57688
|
+
const bg2 = d ? "#000000" : "#ffffff";
|
|
57689
|
+
const border = d ? "rgba(255,255,255,0.12)" : "rgba(0,0,0,0.12)";
|
|
57690
|
+
const borderSubtle = d ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.06)";
|
|
57691
|
+
const text = d ? "#ffffff" : "#000000";
|
|
57692
|
+
const textSecondary = d ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)";
|
|
57693
|
+
const textTertiary = d ? "rgba(255,255,255,0.3)" : "rgba(0,0,0,0.3)";
|
|
57694
|
+
const surfaceSubtle = d ? "rgba(255,255,255,0.04)" : "rgba(0,0,0,0.03)";
|
|
57695
|
+
const monoFont = `ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace`;
|
|
57696
|
+
const sansFont = `-apple-system, BlinkMacSystemFont, "Segoe UI", "Inter", Roboto, Helvetica, Arial, sans-serif`;
|
|
57378
57697
|
const css = `
|
|
57379
57698
|
.llm-chat {
|
|
57380
57699
|
display: flex;
|
|
57381
57700
|
flex-direction: column;
|
|
57382
|
-
border
|
|
57383
|
-
|
|
57384
|
-
background: ${d ? "#0a0a0a" : "#fafafa"};
|
|
57701
|
+
border: 1px solid ${border};
|
|
57702
|
+
background: ${bg2};
|
|
57385
57703
|
overflow: hidden;
|
|
57386
|
-
font-family:
|
|
57387
|
-
color: ${
|
|
57704
|
+
font-family: ${sansFont};
|
|
57705
|
+
color: ${text};
|
|
57388
57706
|
}
|
|
57389
57707
|
|
|
57390
57708
|
/* Header */
|
|
@@ -57393,34 +57711,103 @@ function injectChatStyles(theme) {
|
|
|
57393
57711
|
align-items: center;
|
|
57394
57712
|
justify-content: space-between;
|
|
57395
57713
|
padding: 12px 16px;
|
|
57396
|
-
border-bottom: 1px solid ${
|
|
57397
|
-
font-size: 12px;
|
|
57398
|
-
color: ${d ? "rgba(255,255,255,0.45)" : "rgba(0,0,0,0.45)"};
|
|
57714
|
+
border-bottom: 1px solid ${borderSubtle};
|
|
57399
57715
|
}
|
|
57400
|
-
|
|
57401
|
-
|
|
57402
|
-
|
|
57716
|
+
|
|
57717
|
+
/* Model Selector */
|
|
57718
|
+
.llm-chat-model-select {
|
|
57719
|
+
position: relative;
|
|
57403
57720
|
}
|
|
57404
|
-
.llm-chat-
|
|
57721
|
+
.llm-chat-model-btn {
|
|
57405
57722
|
display: flex;
|
|
57406
57723
|
align-items: center;
|
|
57407
57724
|
gap: 6px;
|
|
57725
|
+
background: transparent;
|
|
57726
|
+
border: none;
|
|
57727
|
+
color: ${text};
|
|
57728
|
+
font-weight: 400;
|
|
57729
|
+
font-size: 11px;
|
|
57730
|
+
font-family: ${monoFont};
|
|
57731
|
+
text-transform: uppercase;
|
|
57732
|
+
letter-spacing: 0.05em;
|
|
57733
|
+
padding: 4px 0;
|
|
57734
|
+
cursor: pointer;
|
|
57735
|
+
transition: opacity 0.1s;
|
|
57736
|
+
}
|
|
57737
|
+
.llm-chat-model-btn:hover {
|
|
57738
|
+
opacity: 0.6;
|
|
57739
|
+
}
|
|
57740
|
+
.llm-chat-model-menu {
|
|
57741
|
+
position: absolute;
|
|
57742
|
+
top: 100%;
|
|
57743
|
+
left: 0;
|
|
57744
|
+
margin-top: 4px;
|
|
57745
|
+
width: 280px;
|
|
57746
|
+
max-height: 300px;
|
|
57747
|
+
overflow-y: auto;
|
|
57748
|
+
background: ${d ? "#0a0a0a" : "#fafafa"};
|
|
57749
|
+
border: 1px solid ${border};
|
|
57750
|
+
z-index: 50;
|
|
57751
|
+
padding: 4px 0;
|
|
57752
|
+
scrollbar-width: thin;
|
|
57753
|
+
}
|
|
57754
|
+
.llm-chat-model-group {
|
|
57755
|
+
padding: 8px 12px 4px;
|
|
57756
|
+
font-size: 10px;
|
|
57757
|
+
font-weight: 400;
|
|
57758
|
+
color: ${textSecondary};
|
|
57759
|
+
text-transform: uppercase;
|
|
57760
|
+
letter-spacing: 0.08em;
|
|
57761
|
+
font-family: ${monoFont};
|
|
57762
|
+
}
|
|
57763
|
+
.llm-chat-model-item {
|
|
57764
|
+
display: block;
|
|
57765
|
+
width: 100%;
|
|
57766
|
+
text-align: left;
|
|
57767
|
+
padding: 6px 12px;
|
|
57768
|
+
font-size: 12px;
|
|
57769
|
+
font-family: ${monoFont};
|
|
57770
|
+
color: ${textSecondary};
|
|
57771
|
+
background: transparent;
|
|
57772
|
+
border: none;
|
|
57773
|
+
cursor: pointer;
|
|
57774
|
+
white-space: nowrap;
|
|
57775
|
+
overflow: hidden;
|
|
57776
|
+
text-overflow: ellipsis;
|
|
57777
|
+
transition: color 0.1s;
|
|
57778
|
+
}
|
|
57779
|
+
.llm-chat-model-item:hover {
|
|
57780
|
+
color: ${text};
|
|
57781
|
+
}
|
|
57782
|
+
.llm-chat-model-item--active {
|
|
57783
|
+
color: ${text};
|
|
57784
|
+
}
|
|
57785
|
+
|
|
57786
|
+
/* Status */
|
|
57787
|
+
.llm-chat-status {
|
|
57788
|
+
display: flex;
|
|
57789
|
+
align-items: center;
|
|
57790
|
+
gap: 8px;
|
|
57791
|
+
font-size: 10px;
|
|
57792
|
+
font-family: ${monoFont};
|
|
57793
|
+
text-transform: uppercase;
|
|
57794
|
+
letter-spacing: 0.08em;
|
|
57795
|
+
color: ${textSecondary};
|
|
57408
57796
|
}
|
|
57409
57797
|
.llm-chat-dot {
|
|
57410
|
-
width:
|
|
57411
|
-
height:
|
|
57798
|
+
width: 5px;
|
|
57799
|
+
height: 5px;
|
|
57412
57800
|
border-radius: 50%;
|
|
57413
|
-
flex-shrink: 0;
|
|
57414
57801
|
}
|
|
57415
57802
|
.llm-chat-dot--loading {
|
|
57416
|
-
background:
|
|
57417
|
-
animation: llm-pulse 1.5s
|
|
57803
|
+
background: ${textSecondary};
|
|
57804
|
+
animation: llm-pulse 1.5s infinite;
|
|
57418
57805
|
}
|
|
57419
57806
|
.llm-chat-dot--ready {
|
|
57420
|
-
background:
|
|
57807
|
+
background: ${text};
|
|
57421
57808
|
}
|
|
57422
57809
|
.llm-chat-dot--error {
|
|
57423
|
-
background: #
|
|
57810
|
+
background: #ff3333;
|
|
57424
57811
|
}
|
|
57425
57812
|
|
|
57426
57813
|
/* Progress */
|
|
@@ -57428,122 +57815,144 @@ function injectChatStyles(theme) {
|
|
|
57428
57815
|
padding: 0 16px 8px;
|
|
57429
57816
|
}
|
|
57430
57817
|
.llm-chat-progress-bar {
|
|
57431
|
-
height:
|
|
57432
|
-
|
|
57433
|
-
background: ${d ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.06)"};
|
|
57818
|
+
height: 1px;
|
|
57819
|
+
background: ${borderSubtle};
|
|
57434
57820
|
overflow: hidden;
|
|
57435
57821
|
}
|
|
57436
57822
|
.llm-chat-progress-fill {
|
|
57437
57823
|
height: 100%;
|
|
57438
|
-
|
|
57439
|
-
background: linear-gradient(90deg, #38bdf8, #818cf8);
|
|
57824
|
+
background: ${text};
|
|
57440
57825
|
transition: width 0.3s ease;
|
|
57441
57826
|
}
|
|
57442
57827
|
.llm-chat-progress-text {
|
|
57443
|
-
font-size:
|
|
57444
|
-
|
|
57828
|
+
font-size: 10px;
|
|
57829
|
+
font-family: ${monoFont};
|
|
57830
|
+
color: ${textTertiary};
|
|
57445
57831
|
margin-top: 4px;
|
|
57832
|
+
text-align: right;
|
|
57833
|
+
text-transform: uppercase;
|
|
57834
|
+
letter-spacing: 0.05em;
|
|
57446
57835
|
}
|
|
57447
57836
|
|
|
57448
57837
|
/* Messages */
|
|
57449
57838
|
.llm-chat-messages {
|
|
57450
57839
|
flex: 1;
|
|
57451
57840
|
overflow-y: auto;
|
|
57452
|
-
padding: 16px;
|
|
57841
|
+
padding: 20px 16px;
|
|
57453
57842
|
display: flex;
|
|
57454
57843
|
flex-direction: column;
|
|
57455
|
-
gap:
|
|
57844
|
+
gap: 24px;
|
|
57456
57845
|
scrollbar-width: thin;
|
|
57457
|
-
scrollbar-color: ${d ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.1)"} transparent;
|
|
57458
57846
|
}
|
|
57459
|
-
|
|
57847
|
+
|
|
57460
57848
|
/* Welcome */
|
|
57461
57849
|
.llm-chat-welcome {
|
|
57462
57850
|
display: flex;
|
|
57463
|
-
|
|
57851
|
+
flex-direction: column;
|
|
57852
|
+
align-items: flex-start;
|
|
57464
57853
|
justify-content: center;
|
|
57465
57854
|
flex: 1;
|
|
57466
|
-
|
|
57467
|
-
|
|
57468
|
-
|
|
57469
|
-
|
|
57470
|
-
|
|
57855
|
+
color: ${textTertiary};
|
|
57856
|
+
padding: 40px 0;
|
|
57857
|
+
}
|
|
57858
|
+
.llm-chat-welcome h3 {
|
|
57859
|
+
font-size: 11px;
|
|
57860
|
+
font-weight: 400;
|
|
57861
|
+
font-family: ${monoFont};
|
|
57862
|
+
text-transform: uppercase;
|
|
57863
|
+
letter-spacing: 0.08em;
|
|
57864
|
+
color: ${textSecondary};
|
|
57865
|
+
margin: 0 0 8px;
|
|
57866
|
+
}
|
|
57867
|
+
.llm-chat-welcome p {
|
|
57868
|
+
font-size: 13px;
|
|
57869
|
+
margin: 0;
|
|
57870
|
+
max-width: 360px;
|
|
57871
|
+
line-height: 1.6;
|
|
57872
|
+
color: ${textTertiary};
|
|
57471
57873
|
}
|
|
57472
57874
|
|
|
57473
57875
|
/* Bubble */
|
|
57474
57876
|
.llm-chat-bubble {
|
|
57475
57877
|
display: flex;
|
|
57476
|
-
|
|
57477
|
-
|
|
57878
|
+
flex-direction: column;
|
|
57879
|
+
max-width: 100%;
|
|
57478
57880
|
}
|
|
57479
57881
|
.llm-chat-bubble--user {
|
|
57480
57882
|
align-self: flex-end;
|
|
57883
|
+
max-width: 80%;
|
|
57481
57884
|
}
|
|
57482
57885
|
.llm-chat-bubble--assistant {
|
|
57483
57886
|
align-self: flex-start;
|
|
57887
|
+
width: 100%;
|
|
57484
57888
|
}
|
|
57485
|
-
|
|
57889
|
+
|
|
57890
|
+
/* User message — flat, subtle bg, no radius */
|
|
57891
|
+
.llm-chat-user-content {
|
|
57486
57892
|
padding: 10px 14px;
|
|
57487
|
-
border-radius: 16px;
|
|
57488
57893
|
font-size: 14px;
|
|
57489
|
-
line-height: 1.
|
|
57894
|
+
line-height: 1.6;
|
|
57490
57895
|
white-space: pre-wrap;
|
|
57491
|
-
|
|
57492
|
-
|
|
57493
|
-
|
|
57494
|
-
background: linear-gradient(135deg, #38bdf8, #818cf8);
|
|
57495
|
-
color: white;
|
|
57496
|
-
border-bottom-right-radius: 4px;
|
|
57896
|
+
background: ${surfaceSubtle};
|
|
57897
|
+
border: 1px solid ${borderSubtle};
|
|
57898
|
+
color: ${text};
|
|
57497
57899
|
}
|
|
57498
|
-
|
|
57499
|
-
|
|
57500
|
-
|
|
57501
|
-
|
|
57502
|
-
|
|
57503
|
-
|
|
57504
|
-
/* Streaming */
|
|
57505
|
-
.llm-chat-streaming .llm-chat-bubble-content {
|
|
57506
|
-
border: 1px solid ${d ? "rgba(56,189,248,0.2)" : "rgba(59,130,246,0.2)"};
|
|
57900
|
+
|
|
57901
|
+
/* Assistant message */
|
|
57902
|
+
.llm-chat-assistant-content {
|
|
57903
|
+
font-size: 14px;
|
|
57904
|
+
line-height: 1.7;
|
|
57905
|
+
color: ${d ? "rgba(255,255,255,0.85)" : "rgba(0,0,0,0.85)"};
|
|
57507
57906
|
}
|
|
57508
|
-
|
|
57509
|
-
|
|
57510
|
-
|
|
57511
|
-
|
|
57512
|
-
|
|
57513
|
-
|
|
57514
|
-
|
|
57515
|
-
|
|
57907
|
+
|
|
57908
|
+
/* Streamdown Overrides */
|
|
57909
|
+
.llm-chat-assistant-content pre {
|
|
57910
|
+
background: ${surfaceSubtle} !important;
|
|
57911
|
+
border: 1px solid ${borderSubtle} !important;
|
|
57912
|
+
border-radius: 0 !important;
|
|
57913
|
+
padding: 12px !important;
|
|
57914
|
+
margin: 12px 0 !important;
|
|
57915
|
+
}
|
|
57916
|
+
.llm-chat-assistant-content code {
|
|
57917
|
+
font-family: ${monoFont} !important;
|
|
57918
|
+
font-size: 13px !important;
|
|
57919
|
+
}
|
|
57920
|
+
.llm-chat-assistant-content :not(pre) > code {
|
|
57921
|
+
background: ${surfaceSubtle};
|
|
57922
|
+
border: 1px solid ${borderSubtle};
|
|
57923
|
+
padding: 1px 5px;
|
|
57924
|
+
font-size: 12.5px !important;
|
|
57516
57925
|
}
|
|
57517
|
-
|
|
57518
|
-
/*
|
|
57519
|
-
.llm-chat-
|
|
57926
|
+
|
|
57927
|
+
/* Attachments in message */
|
|
57928
|
+
.llm-chat-msg-images {
|
|
57520
57929
|
display: flex;
|
|
57521
|
-
|
|
57522
|
-
|
|
57930
|
+
flex-wrap: wrap;
|
|
57931
|
+
gap: 6px;
|
|
57932
|
+
margin-bottom: 8px;
|
|
57933
|
+
justify-content: flex-end;
|
|
57523
57934
|
}
|
|
57524
|
-
.llm-chat-
|
|
57525
|
-
|
|
57526
|
-
|
|
57527
|
-
|
|
57528
|
-
|
|
57529
|
-
border-radius: 12px;
|
|
57935
|
+
.llm-chat-msg-img {
|
|
57936
|
+
width: 100px;
|
|
57937
|
+
height: 100px;
|
|
57938
|
+
object-fit: cover;
|
|
57939
|
+
border: 1px solid ${border};
|
|
57530
57940
|
}
|
|
57531
57941
|
|
|
57532
57942
|
/* Error */
|
|
57533
57943
|
.llm-chat-error {
|
|
57534
57944
|
margin: 0 16px;
|
|
57535
57945
|
padding: 10px 14px;
|
|
57536
|
-
border
|
|
57537
|
-
background: ${d ? "rgba(239,68,68,0.08)" : "rgba(239,68,68,0.05)"};
|
|
57538
|
-
border: 1px solid ${d ? "rgba(239,68,68,0.2)" : "rgba(239,68,68,0.15)"};
|
|
57946
|
+
border: 1px solid ${d ? "rgba(255,50,50,0.2)" : "rgba(200,0,0,0.15)"};
|
|
57539
57947
|
display: flex;
|
|
57540
57948
|
align-items: center;
|
|
57541
57949
|
justify-content: space-between;
|
|
57542
|
-
gap:
|
|
57950
|
+
gap: 12px;
|
|
57543
57951
|
}
|
|
57544
57952
|
.llm-chat-error-text {
|
|
57545
|
-
font-size:
|
|
57546
|
-
|
|
57953
|
+
font-size: 12px;
|
|
57954
|
+
font-family: ${monoFont};
|
|
57955
|
+
color: ${d ? "#ff6666" : "#cc0000"};
|
|
57547
57956
|
flex: 1;
|
|
57548
57957
|
}
|
|
57549
57958
|
.llm-chat-error-retry {
|
|
@@ -57551,63 +57960,28 @@ function injectChatStyles(theme) {
|
|
|
57551
57960
|
align-items: center;
|
|
57552
57961
|
gap: 4px;
|
|
57553
57962
|
padding: 4px 10px;
|
|
57554
|
-
border
|
|
57555
|
-
border: 1px solid ${d ? "rgba(239,68,68,0.3)" : "rgba(239,68,68,0.2)"};
|
|
57963
|
+
border: 1px solid ${d ? "rgba(255,50,50,0.3)" : "rgba(200,0,0,0.2)"};
|
|
57556
57964
|
background: transparent;
|
|
57557
|
-
color: ${d ? "#
|
|
57558
|
-
font-size:
|
|
57965
|
+
color: ${d ? "#ff6666" : "#cc0000"};
|
|
57966
|
+
font-size: 11px;
|
|
57967
|
+
font-family: ${monoFont};
|
|
57968
|
+
text-transform: uppercase;
|
|
57969
|
+
letter-spacing: 0.05em;
|
|
57559
57970
|
cursor: pointer;
|
|
57560
|
-
transition: background 0.15s;
|
|
57561
|
-
flex-shrink: 0;
|
|
57562
57971
|
}
|
|
57563
57972
|
.llm-chat-error-retry:hover {
|
|
57564
|
-
background: ${d ? "rgba(
|
|
57565
|
-
}
|
|
57566
|
-
|
|
57567
|
-
/* Loading overlay */
|
|
57568
|
-
.llm-chat-loading {
|
|
57569
|
-
display: flex;
|
|
57570
|
-
flex-direction: column;
|
|
57571
|
-
align-items: center;
|
|
57572
|
-
justify-content: center;
|
|
57573
|
-
gap: 12px;
|
|
57574
|
-
flex: 1;
|
|
57575
|
-
padding: 40px 20px;
|
|
57576
|
-
}
|
|
57577
|
-
.llm-chat-spinner {
|
|
57578
|
-
width: 28px;
|
|
57579
|
-
height: 28px;
|
|
57580
|
-
border: 2.5px solid ${d ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.08)"};
|
|
57581
|
-
border-top-color: #38bdf8;
|
|
57582
|
-
border-radius: 50%;
|
|
57583
|
-
animation: llm-spin 0.7s linear infinite;
|
|
57584
|
-
}
|
|
57585
|
-
.llm-chat-loading-text {
|
|
57586
|
-
font-size: 13px;
|
|
57587
|
-
color: ${d ? "rgba(255,255,255,0.4)" : "rgba(0,0,0,0.4)"};
|
|
57973
|
+
background: ${d ? "rgba(255,50,50,0.08)" : "rgba(200,0,0,0.04)"};
|
|
57588
57974
|
}
|
|
57589
57975
|
|
|
57590
|
-
/* Input
|
|
57976
|
+
/* Input Area */
|
|
57591
57977
|
.llm-chat-input-area {
|
|
57592
|
-
padding:
|
|
57593
|
-
border-top: 1px solid ${
|
|
57978
|
+
padding: 12px 16px 16px;
|
|
57979
|
+
border-top: 1px solid ${borderSubtle};
|
|
57594
57980
|
}
|
|
57595
57981
|
|
|
57596
|
-
/* Animations */
|
|
57597
|
-
@keyframes llm-fadein {
|
|
57598
|
-
from { opacity: 0; transform: translateY(4px); }
|
|
57599
|
-
to { opacity: 1; transform: translateY(0); }
|
|
57600
|
-
}
|
|
57601
57982
|
@keyframes llm-pulse {
|
|
57602
57983
|
0%, 100% { opacity: 1; }
|
|
57603
|
-
50% { opacity: 0.
|
|
57604
|
-
}
|
|
57605
|
-
@keyframes llm-blink {
|
|
57606
|
-
0%, 100% { opacity: 1; }
|
|
57607
|
-
50% { opacity: 0; }
|
|
57608
|
-
}
|
|
57609
|
-
@keyframes llm-spin {
|
|
57610
|
-
to { transform: rotate(360deg); }
|
|
57984
|
+
50% { opacity: 0.2; }
|
|
57611
57985
|
}
|
|
57612
57986
|
`;
|
|
57613
57987
|
const style = document.createElement("style");
|
|
@@ -57615,8 +57989,77 @@ function injectChatStyles(theme) {
|
|
|
57615
57989
|
style.textContent = css;
|
|
57616
57990
|
document.head.appendChild(style);
|
|
57617
57991
|
}
|
|
57992
|
+
function ModelSelector({
|
|
57993
|
+
currentModel,
|
|
57994
|
+
onSelect,
|
|
57995
|
+
theme
|
|
57996
|
+
}) {
|
|
57997
|
+
const [isOpen, setIsOpen] = useState2(false);
|
|
57998
|
+
const ref = useRef2(null);
|
|
57999
|
+
useEffect2(() => {
|
|
58000
|
+
function handleClickOutside(event) {
|
|
58001
|
+
if (ref.current && !ref.current.contains(event.target)) {
|
|
58002
|
+
setIsOpen(false);
|
|
58003
|
+
}
|
|
58004
|
+
}
|
|
58005
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
58006
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
58007
|
+
}, []);
|
|
58008
|
+
const displayModel = useMemo(() => {
|
|
58009
|
+
if (!currentModel)
|
|
58010
|
+
return "Select Model";
|
|
58011
|
+
const id2 = currentModel.split("/").pop() || currentModel;
|
|
58012
|
+
return id2.length > 25 ? id2.substring(0, 25) + "..." : id2;
|
|
58013
|
+
}, [currentModel]);
|
|
58014
|
+
return /* @__PURE__ */ jsxDEV2("div", {
|
|
58015
|
+
className: "llm-chat-model-select",
|
|
58016
|
+
ref,
|
|
58017
|
+
children: [
|
|
58018
|
+
/* @__PURE__ */ jsxDEV2("button", {
|
|
58019
|
+
type: "button",
|
|
58020
|
+
className: "llm-chat-model-btn",
|
|
58021
|
+
onClick: () => setIsOpen(!isOpen),
|
|
58022
|
+
children: [
|
|
58023
|
+
"[",
|
|
58024
|
+
displayModel,
|
|
58025
|
+
"] ",
|
|
58026
|
+
/* @__PURE__ */ jsxDEV2(ChevronDownIcon, {}, undefined, false, undefined, this)
|
|
58027
|
+
]
|
|
58028
|
+
}, undefined, true, undefined, this),
|
|
58029
|
+
isOpen && /* @__PURE__ */ jsxDEV2("div", {
|
|
58030
|
+
className: "llm-chat-model-menu",
|
|
58031
|
+
children: [
|
|
58032
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
58033
|
+
className: "llm-chat-model-group",
|
|
58034
|
+
children: "[WebLLM]"
|
|
58035
|
+
}, undefined, false, undefined, this),
|
|
58036
|
+
Object.entries(WEBLLM_MODELS).map(([key, value]) => /* @__PURE__ */ jsxDEV2("button", {
|
|
58037
|
+
className: `llm-chat-model-item ${currentModel === value ? "llm-chat-model-item--active" : ""}`,
|
|
58038
|
+
onClick: () => {
|
|
58039
|
+
onSelect(value);
|
|
58040
|
+
setIsOpen(false);
|
|
58041
|
+
},
|
|
58042
|
+
children: key
|
|
58043
|
+
}, key, false, undefined, this)),
|
|
58044
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
58045
|
+
className: "llm-chat-model-group",
|
|
58046
|
+
children: "[Transformers.js]"
|
|
58047
|
+
}, undefined, false, undefined, this),
|
|
58048
|
+
Object.entries(TRANSFORMERS_MODELS).map(([key, value]) => /* @__PURE__ */ jsxDEV2("button", {
|
|
58049
|
+
className: `llm-chat-model-item ${currentModel === value ? "llm-chat-model-item--active" : ""}`,
|
|
58050
|
+
onClick: () => {
|
|
58051
|
+
onSelect(value);
|
|
58052
|
+
setIsOpen(false);
|
|
58053
|
+
},
|
|
58054
|
+
children: key
|
|
58055
|
+
}, key, false, undefined, this))
|
|
58056
|
+
]
|
|
58057
|
+
}, undefined, true, undefined, this)
|
|
58058
|
+
]
|
|
58059
|
+
}, undefined, true, undefined, this);
|
|
58060
|
+
}
|
|
57618
58061
|
function Chat2({
|
|
57619
|
-
systemPrompt =
|
|
58062
|
+
systemPrompt = DEFAULT_SYSTEM_PROMPT,
|
|
57620
58063
|
placeholder = "Type a message...",
|
|
57621
58064
|
theme = "dark",
|
|
57622
58065
|
className,
|
|
@@ -57627,14 +58070,16 @@ function Chat2({
|
|
|
57627
58070
|
onError: onErrorProp,
|
|
57628
58071
|
showHeader = true,
|
|
57629
58072
|
showProgress = true,
|
|
57630
|
-
welcomeMessage = "
|
|
58073
|
+
welcomeMessage = "Ready to assist",
|
|
58074
|
+
onModelChange
|
|
57631
58075
|
}) {
|
|
57632
|
-
const { llm, isLoading, isReady, loadProgress, error, modelId,
|
|
57633
|
-
const [messages, setMessages] =
|
|
57634
|
-
const [input, setInput] =
|
|
57635
|
-
const [isGenerating, setIsGenerating] =
|
|
57636
|
-
const [streamingText, setStreamingText] =
|
|
57637
|
-
const [pendingMessage, setPendingMessage] =
|
|
58076
|
+
const { llm, isLoading, isReady, loadProgress, error, modelId, reload } = useLLM();
|
|
58077
|
+
const [messages, setMessages] = useState2([]);
|
|
58078
|
+
const [input, setInput] = useState2("");
|
|
58079
|
+
const [isGenerating, setIsGenerating] = useState2(false);
|
|
58080
|
+
const [streamingText, setStreamingText] = useState2("");
|
|
58081
|
+
const [pendingMessage, setPendingMessage] = useState2(null);
|
|
58082
|
+
const [images, setImages] = useState2([]);
|
|
57638
58083
|
const messagesEndRef = useRef2(null);
|
|
57639
58084
|
const abortRef = useRef2(false);
|
|
57640
58085
|
const isProcessingRef = useRef2(false);
|
|
@@ -57643,21 +58088,28 @@ function Chat2({
|
|
|
57643
58088
|
}, [theme]);
|
|
57644
58089
|
useEffect2(() => {
|
|
57645
58090
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
57646
|
-
}, [messages, streamingText]);
|
|
57647
|
-
const generate = async (userContent, currentMessages) => {
|
|
58091
|
+
}, [messages, streamingText, isGenerating]);
|
|
58092
|
+
const generate = async (userContent, currentMessages, attachedImages = []) => {
|
|
57648
58093
|
if (!llm || !isReady || isProcessingRef.current)
|
|
57649
58094
|
return;
|
|
57650
58095
|
isProcessingRef.current = true;
|
|
57651
|
-
const userMsg = {
|
|
58096
|
+
const userMsg = {
|
|
58097
|
+
role: "user",
|
|
58098
|
+
content: userContent,
|
|
58099
|
+
images: attachedImages
|
|
58100
|
+
};
|
|
57652
58101
|
setMessages((prev) => [...prev, userMsg]);
|
|
58102
|
+
setIsGenerating(true);
|
|
58103
|
+
setStreamingText("");
|
|
58104
|
+
abortRef.current = false;
|
|
57653
58105
|
const apiMessages = [];
|
|
57654
58106
|
if (systemPrompt) {
|
|
57655
58107
|
apiMessages.push({ role: "system", content: systemPrompt });
|
|
57656
58108
|
}
|
|
57657
|
-
|
|
57658
|
-
|
|
57659
|
-
|
|
57660
|
-
|
|
58109
|
+
currentMessages.forEach((m) => {
|
|
58110
|
+
apiMessages.push({ role: m.role, content: m.content });
|
|
58111
|
+
});
|
|
58112
|
+
apiMessages.push({ role: "user", content: userContent });
|
|
57661
58113
|
try {
|
|
57662
58114
|
const response = await llm.stream(apiMessages, (_token, fullText) => {
|
|
57663
58115
|
if (abortRef.current)
|
|
@@ -57673,29 +58125,26 @@ function Chat2({
|
|
|
57673
58125
|
} catch (err) {
|
|
57674
58126
|
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
57675
58127
|
onErrorProp?.(error2);
|
|
58128
|
+
setMessages((prev) => [...prev, {
|
|
58129
|
+
role: "assistant",
|
|
58130
|
+
content: `Error: ${error2.message}`
|
|
58131
|
+
}]);
|
|
57676
58132
|
} finally {
|
|
57677
58133
|
setIsGenerating(false);
|
|
57678
58134
|
isProcessingRef.current = false;
|
|
57679
58135
|
}
|
|
57680
58136
|
};
|
|
57681
|
-
useEffect2(() => {
|
|
57682
|
-
if (isReady && pendingMessage && !isProcessingRef.current) {
|
|
57683
|
-
const msg = pendingMessage;
|
|
57684
|
-
setPendingMessage(null);
|
|
57685
|
-
generate(msg, messages);
|
|
57686
|
-
}
|
|
57687
|
-
}, [isReady, pendingMessage]);
|
|
57688
58137
|
const handleSend = () => {
|
|
57689
58138
|
const text = input.trim();
|
|
57690
|
-
if (!text)
|
|
58139
|
+
if (!text && images.length === 0)
|
|
57691
58140
|
return;
|
|
58141
|
+
const currentImages = [...images];
|
|
57692
58142
|
setInput("");
|
|
58143
|
+
setImages([]);
|
|
57693
58144
|
onSendProp?.(text);
|
|
57694
58145
|
if (llm && isReady) {
|
|
57695
|
-
generate(text, messages);
|
|
58146
|
+
generate(text, messages, currentImages);
|
|
57696
58147
|
} else if (isLoading) {
|
|
57697
|
-
const userMsg = { role: "user", content: text };
|
|
57698
|
-
setMessages((prev) => [...prev, userMsg]);
|
|
57699
58148
|
setPendingMessage(text);
|
|
57700
58149
|
}
|
|
57701
58150
|
};
|
|
@@ -57708,7 +58157,7 @@ function Chat2({
|
|
|
57708
58157
|
}
|
|
57709
58158
|
};
|
|
57710
58159
|
const statusDotClass = error ? "llm-chat-dot llm-chat-dot--error" : isReady ? "llm-chat-dot llm-chat-dot--ready" : "llm-chat-dot llm-chat-dot--loading";
|
|
57711
|
-
const statusText = error ? "Error" : isReady ? "Ready" : isLoading ? "Loading
|
|
58160
|
+
const statusText = error ? "Error" : isReady ? "Ready" : isLoading ? "Loading" : "Idle";
|
|
57712
58161
|
return /* @__PURE__ */ jsxDEV2("div", {
|
|
57713
58162
|
className: `llm-chat${className ? ` ${className}` : ""}`,
|
|
57714
58163
|
style: { maxHeight, height: "100%" },
|
|
@@ -57716,28 +58165,34 @@ function Chat2({
|
|
|
57716
58165
|
showHeader && /* @__PURE__ */ jsxDEV2("div", {
|
|
57717
58166
|
className: "llm-chat-header",
|
|
57718
58167
|
children: [
|
|
57719
|
-
/* @__PURE__ */ jsxDEV2(
|
|
57720
|
-
|
|
57721
|
-
|
|
57722
|
-
|
|
57723
|
-
|
|
57724
|
-
|
|
57725
|
-
|
|
57726
|
-
|
|
57727
|
-
|
|
57728
|
-
|
|
57729
|
-
|
|
57730
|
-
|
|
57731
|
-
|
|
57732
|
-
|
|
58168
|
+
onModelChange ? /* @__PURE__ */ jsxDEV2(ModelSelector, {
|
|
58169
|
+
currentModel: modelId,
|
|
58170
|
+
onSelect: onModelChange,
|
|
58171
|
+
theme
|
|
58172
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV2("div", {
|
|
58173
|
+
className: "llm-chat-model-select",
|
|
58174
|
+
children: /* @__PURE__ */ jsxDEV2("span", {
|
|
58175
|
+
style: {
|
|
58176
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
58177
|
+
fontSize: "11px",
|
|
58178
|
+
textTransform: "uppercase",
|
|
58179
|
+
letterSpacing: "0.05em"
|
|
58180
|
+
},
|
|
58181
|
+
children: [
|
|
58182
|
+
"[",
|
|
58183
|
+
modelId?.split("/").pop(),
|
|
58184
|
+
"]"
|
|
58185
|
+
]
|
|
58186
|
+
}, undefined, true, undefined, this)
|
|
58187
|
+
}, undefined, false, undefined, this),
|
|
57733
58188
|
/* @__PURE__ */ jsxDEV2("div", {
|
|
57734
|
-
className: "llm-chat-
|
|
58189
|
+
className: "llm-chat-status",
|
|
57735
58190
|
children: [
|
|
57736
|
-
/* @__PURE__ */ jsxDEV2("span", {
|
|
57737
|
-
className: statusDotClass
|
|
57738
|
-
}, undefined, false, undefined, this),
|
|
57739
58191
|
/* @__PURE__ */ jsxDEV2("span", {
|
|
57740
58192
|
children: statusText
|
|
58193
|
+
}, undefined, false, undefined, this),
|
|
58194
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
58195
|
+
className: statusDotClass
|
|
57741
58196
|
}, undefined, false, undefined, this)
|
|
57742
58197
|
]
|
|
57743
58198
|
}, undefined, true, undefined, this)
|
|
@@ -57779,50 +58234,54 @@ function Chat2({
|
|
|
57779
58234
|
/* @__PURE__ */ jsxDEV2("div", {
|
|
57780
58235
|
className: "llm-chat-messages",
|
|
57781
58236
|
children: [
|
|
57782
|
-
isLoading && messages.length === 0 && !error && /* @__PURE__ */ jsxDEV2("div", {
|
|
57783
|
-
className: "llm-chat-
|
|
58237
|
+
!isLoading && messages.length === 0 && !error && /* @__PURE__ */ jsxDEV2("div", {
|
|
58238
|
+
className: "llm-chat-welcome",
|
|
57784
58239
|
children: [
|
|
57785
|
-
/* @__PURE__ */ jsxDEV2("
|
|
57786
|
-
|
|
57787
|
-
|
|
57788
|
-
|
|
57789
|
-
|
|
57790
|
-
|
|
58240
|
+
/* @__PURE__ */ jsxDEV2("h3", {
|
|
58241
|
+
children: [
|
|
58242
|
+
"[",
|
|
58243
|
+
welcomeMessage,
|
|
58244
|
+
"]"
|
|
58245
|
+
]
|
|
58246
|
+
}, undefined, true, undefined, this),
|
|
58247
|
+
/* @__PURE__ */ jsxDEV2("p", {
|
|
58248
|
+
children: "Markdown, code blocks, Mermaid diagrams. Paste images with Ctrl+V."
|
|
57791
58249
|
}, undefined, false, undefined, this)
|
|
57792
58250
|
]
|
|
57793
58251
|
}, undefined, true, undefined, this),
|
|
57794
|
-
|
|
57795
|
-
className:
|
|
57796
|
-
children:
|
|
57797
|
-
|
|
57798
|
-
|
|
57799
|
-
|
|
57800
|
-
|
|
57801
|
-
|
|
57802
|
-
|
|
57803
|
-
|
|
57804
|
-
|
|
58252
|
+
messages.map((msg, i) => /* @__PURE__ */ jsxDEV2("div", {
|
|
58253
|
+
className: `llm-chat-bubble llm-chat-bubble--${msg.role}`,
|
|
58254
|
+
children: msg.role === "user" ? /* @__PURE__ */ jsxDEV2(Fragment2, {
|
|
58255
|
+
children: [
|
|
58256
|
+
msg.images && msg.images.length > 0 && /* @__PURE__ */ jsxDEV2("div", {
|
|
58257
|
+
className: "llm-chat-msg-images",
|
|
58258
|
+
children: msg.images.map((img) => /* @__PURE__ */ jsxDEV2("img", {
|
|
58259
|
+
src: img.dataUrl,
|
|
58260
|
+
className: "llm-chat-msg-img",
|
|
58261
|
+
alt: "attachment"
|
|
58262
|
+
}, img.id, false, undefined, this))
|
|
58263
|
+
}, undefined, false, undefined, this),
|
|
58264
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
58265
|
+
className: "llm-chat-user-content",
|
|
58266
|
+
children: msg.content
|
|
58267
|
+
}, undefined, false, undefined, this)
|
|
58268
|
+
]
|
|
58269
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV2("div", {
|
|
58270
|
+
className: "llm-chat-assistant-content",
|
|
58271
|
+
children: /* @__PURE__ */ jsxDEV2(Streamdown, {
|
|
58272
|
+
plugins: { code, mermaid },
|
|
57805
58273
|
children: msg.content
|
|
57806
58274
|
}, undefined, false, undefined, this)
|
|
57807
|
-
},
|
|
57808
|
-
}),
|
|
58275
|
+
}, undefined, false, undefined, this)
|
|
58276
|
+
}, i, false, undefined, this)),
|
|
57809
58277
|
streamingText && /* @__PURE__ */ jsxDEV2("div", {
|
|
57810
|
-
className: "llm-chat-bubble llm-chat-bubble--assistant
|
|
58278
|
+
className: "llm-chat-bubble llm-chat-bubble--assistant",
|
|
57811
58279
|
children: /* @__PURE__ */ jsxDEV2("div", {
|
|
57812
|
-
className: "llm-chat-
|
|
57813
|
-
children:
|
|
57814
|
-
|
|
57815
|
-
|
|
57816
|
-
|
|
57817
|
-
}, undefined, false, undefined, this)
|
|
57818
|
-
]
|
|
57819
|
-
}, undefined, true, undefined, this)
|
|
57820
|
-
}, undefined, false, undefined, this),
|
|
57821
|
-
pendingMessage !== null && /* @__PURE__ */ jsxDEV2("div", {
|
|
57822
|
-
className: "llm-chat-pending",
|
|
57823
|
-
children: /* @__PURE__ */ jsxDEV2("span", {
|
|
57824
|
-
className: "llm-chat-pending-badge",
|
|
57825
|
-
children: "⏳ Waiting for model to load..."
|
|
58280
|
+
className: "llm-chat-assistant-content",
|
|
58281
|
+
children: /* @__PURE__ */ jsxDEV2(Streamdown, {
|
|
58282
|
+
plugins: { code, mermaid },
|
|
58283
|
+
children: streamingText
|
|
58284
|
+
}, undefined, false, undefined, this)
|
|
57826
58285
|
}, undefined, false, undefined, this)
|
|
57827
58286
|
}, undefined, false, undefined, this),
|
|
57828
58287
|
/* @__PURE__ */ jsxDEV2("div", {
|
|
@@ -57839,9 +58298,12 @@ function Chat2({
|
|
|
57839
58298
|
onStop: handleStop,
|
|
57840
58299
|
disabled: !isReady && !isLoading,
|
|
57841
58300
|
isGenerating,
|
|
57842
|
-
placeholder: isLoading ? "
|
|
58301
|
+
placeholder: isLoading ? "Model is loading..." : placeholder,
|
|
57843
58302
|
theme,
|
|
57844
|
-
actions: inputActions
|
|
58303
|
+
actions: inputActions,
|
|
58304
|
+
images,
|
|
58305
|
+
onImageAdd: (img) => setImages((prev) => [...prev, img]),
|
|
58306
|
+
onImageRemove: (id2) => setImages((prev) => prev.filter((img) => img.id !== id2))
|
|
57845
58307
|
}, undefined, false, undefined, this)
|
|
57846
58308
|
}, undefined, false, undefined, this)
|
|
57847
58309
|
]
|
|
@@ -57849,7 +58311,7 @@ function Chat2({
|
|
|
57849
58311
|
}
|
|
57850
58312
|
|
|
57851
58313
|
// src/react/index.tsx
|
|
57852
|
-
import { jsxDEV as jsxDEV3, Fragment } from "react/jsx-dev-runtime";
|
|
58314
|
+
import { jsxDEV as jsxDEV3, Fragment as Fragment3 } from "react/jsx-dev-runtime";
|
|
57853
58315
|
var LLMContext = createContext(null);
|
|
57854
58316
|
function LLMProvider({
|
|
57855
58317
|
children,
|
|
@@ -57859,10 +58321,10 @@ function LLMProvider({
|
|
|
57859
58321
|
onError,
|
|
57860
58322
|
...config
|
|
57861
58323
|
}) {
|
|
57862
|
-
const [llm, setLLM] =
|
|
57863
|
-
const [isLoading, setIsLoading] =
|
|
57864
|
-
const [loadProgress, setLoadProgress] =
|
|
57865
|
-
const [error, setError] =
|
|
58324
|
+
const [llm, setLLM] = useState3(null);
|
|
58325
|
+
const [isLoading, setIsLoading] = useState3(false);
|
|
58326
|
+
const [loadProgress, setLoadProgress] = useState3(null);
|
|
58327
|
+
const [error, setError] = useState3(null);
|
|
57866
58328
|
const hasLoadedRef = useRef3(false);
|
|
57867
58329
|
const configRef = useRef3(config);
|
|
57868
58330
|
configRef.current = config;
|
|
@@ -57916,7 +58378,7 @@ function LLMProvider({
|
|
|
57916
58378
|
}
|
|
57917
58379
|
};
|
|
57918
58380
|
}, [llm]);
|
|
57919
|
-
const value =
|
|
58381
|
+
const value = useMemo2(() => ({
|
|
57920
58382
|
llm,
|
|
57921
58383
|
isLoading,
|
|
57922
58384
|
isReady: llm?.isReady ?? false,
|
|
@@ -57951,11 +58413,11 @@ function useChat(options = {}) {
|
|
|
57951
58413
|
onFinish,
|
|
57952
58414
|
onError
|
|
57953
58415
|
} = options;
|
|
57954
|
-
const [messages, setMessages] =
|
|
57955
|
-
const [input, setInput] =
|
|
57956
|
-
const [isGenerating, setIsGenerating] =
|
|
57957
|
-
const [streamingText, setStreamingText] =
|
|
57958
|
-
const [pendingMessage, setPendingMessage] =
|
|
58416
|
+
const [messages, setMessages] = useState3(initialMessages);
|
|
58417
|
+
const [input, setInput] = useState3("");
|
|
58418
|
+
const [isGenerating, setIsGenerating] = useState3(false);
|
|
58419
|
+
const [streamingText, setStreamingText] = useState3("");
|
|
58420
|
+
const [pendingMessage, setPendingMessage] = useState3(null);
|
|
57959
58421
|
const abortRef = useRef3(false);
|
|
57960
58422
|
const isProcessingRef = useRef3(false);
|
|
57961
58423
|
const generateResponse = useCallback2(async (userContent, currentMessages) => {
|
|
@@ -58077,8 +58539,8 @@ function useChat(options = {}) {
|
|
|
58077
58539
|
function useStream(options = {}) {
|
|
58078
58540
|
const { llm, isReady } = useLLM();
|
|
58079
58541
|
const { generateOptions, onToken, onFinish, onError } = options;
|
|
58080
|
-
const [text, setText] =
|
|
58081
|
-
const [isStreaming, setIsStreaming] =
|
|
58542
|
+
const [text, setText] = useState3("");
|
|
58543
|
+
const [isStreaming, setIsStreaming] = useState3(false);
|
|
58082
58544
|
const abortRef = useRef3(false);
|
|
58083
58545
|
const stream = useCallback2(async (input) => {
|
|
58084
58546
|
if (!llm || !isReady) {
|
|
@@ -58122,8 +58584,8 @@ function useStream(options = {}) {
|
|
|
58122
58584
|
function useCompletion(options = {}) {
|
|
58123
58585
|
const { llm, isReady } = useLLM();
|
|
58124
58586
|
const { generateOptions } = options;
|
|
58125
|
-
const [completion, setCompletion] =
|
|
58126
|
-
const [isLoading, setIsLoading] =
|
|
58587
|
+
const [completion, setCompletion] = useState3("");
|
|
58588
|
+
const [isLoading, setIsLoading] = useState3(false);
|
|
58127
58589
|
const complete = useCallback2(async (prompt) => {
|
|
58128
58590
|
if (!llm || !isReady) {
|
|
58129
58591
|
return "";
|
|
@@ -58179,11 +58641,11 @@ function LLMLoading({ children, className }) {
|
|
|
58179
58641
|
function LLMReady({ children, fallback = null }) {
|
|
58180
58642
|
const { isReady, isLoading } = useLLM();
|
|
58181
58643
|
if (isLoading || !isReady) {
|
|
58182
|
-
return /* @__PURE__ */ jsxDEV3(
|
|
58644
|
+
return /* @__PURE__ */ jsxDEV3(Fragment3, {
|
|
58183
58645
|
children: fallback
|
|
58184
58646
|
}, undefined, false, undefined, this);
|
|
58185
58647
|
}
|
|
58186
|
-
return /* @__PURE__ */ jsxDEV3(
|
|
58648
|
+
return /* @__PURE__ */ jsxDEV3(Fragment3, {
|
|
58187
58649
|
children
|
|
58188
58650
|
}, undefined, false, undefined, this);
|
|
58189
58651
|
}
|