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