@things-factory/ai-assistant 10.1.13 → 10.1.16
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/client/components/{board-ai-chat.ts → assistant-chat.ts} +589 -18
- package/client/components/chat-defaults.ts +24 -0
- package/client/components/chat-input-builder.ts +1 -1
- package/client/index.ts +2 -3
- package/dist-client/components/{board-ai-chat.d.ts → assistant-chat.d.ts} +39 -3
- package/dist-client/components/{board-ai-chat.js → assistant-chat.js} +597 -66
- package/dist-client/components/assistant-chat.js.map +1 -0
- package/dist-client/components/{board-ai-chat.test.js → assistant-chat.test.js} +1 -1
- package/dist-client/components/assistant-chat.test.js.map +1 -0
- package/dist-client/components/chat-defaults.d.ts +22 -0
- package/dist-client/components/chat-defaults.js +4 -0
- package/dist-client/components/chat-defaults.js.map +1 -1
- package/dist-client/components/chat-input-builder.js +1 -1
- package/dist-client/components/chat-input-builder.js.map +1 -1
- package/dist-client/index.d.ts +2 -3
- package/dist-client/index.js +2 -3
- package/dist-client/index.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/service/assistant-chat-resolver.js +12 -0
- package/dist-server/service/assistant-chat-resolver.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/server/service/assistant-chat-resolver.ts +13 -0
- package/test/assistant-request-context.test.ts +1 -1
- package/test/assistant-session-toolbar.test.ts +1 -1
- package/translations/en.json +6 -1
- package/translations/ko.json +6 -1
- package/dist-client/components/board-ai-chat.js.map +0 -1
- package/dist-client/components/board-ai-chat.test.js.map +0 -1
- /package/client/components/{board-ai-chat.test.ts → assistant-chat.test.ts} +0 -0
- /package/dist-client/components/{board-ai-chat.test.d.ts → assistant-chat.test.d.ts} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
var
|
|
1
|
+
var OxAssistantChat_1;
|
|
2
2
|
import { __decorate, __metadata } from "tslib";
|
|
3
3
|
/**
|
|
4
|
-
* <ox-
|
|
4
|
+
* <ox-assistant-chat> — AI 도우미 채팅 컴포넌트 (Lit).
|
|
5
5
|
*
|
|
6
6
|
* 입력:
|
|
7
7
|
* - sessionId: 영속 ChatSession 식별자 (없으면 ad-hoc 모드, 메시지 영속 안 됨)
|
|
@@ -44,6 +44,13 @@ import { buildMentionCandidates, buildCatalogCandidates, buildSlashCandidates, b
|
|
|
44
44
|
*/
|
|
45
45
|
import { chatDefaults } from './chat-defaults.js';
|
|
46
46
|
import { availableTriggers } from './chat-triggers.js';
|
|
47
|
+
function formatFileSize(bytes) {
|
|
48
|
+
if (!bytes || bytes < 1024)
|
|
49
|
+
return `${bytes || 0} B`;
|
|
50
|
+
if (bytes < 1024 * 1024)
|
|
51
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
52
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
53
|
+
}
|
|
47
54
|
const BOARD_AI_CHAT_MUTATION = gql `
|
|
48
55
|
mutation BoardAIChat($input: BoardAIChatInput!) {
|
|
49
56
|
boardAIChat(input: $input) {
|
|
@@ -154,7 +161,7 @@ function initials(name) {
|
|
|
154
161
|
return (parts[0][0] + parts[1][0]).toUpperCase();
|
|
155
162
|
return /[a-zA-Z]/.test(n) ? n.slice(0, 2).toUpperCase() : n.slice(0, 1);
|
|
156
163
|
}
|
|
157
|
-
let
|
|
164
|
+
let OxAssistantChat = class OxAssistantChat extends LitElement {
|
|
158
165
|
constructor() {
|
|
159
166
|
super(...arguments);
|
|
160
167
|
this.adoptingSession = false;
|
|
@@ -206,12 +213,18 @@ let OxBoardAIChat = class OxBoardAIChat extends LitElement {
|
|
|
206
213
|
this.input = '';
|
|
207
214
|
/** 되돌려진 patch id 들 — 한 번 revert 한 patch 는 버튼 비활성 */
|
|
208
215
|
this.revertedPatchIds = new Set();
|
|
216
|
+
/** 첨부된 파일/이미지 목록 */
|
|
217
|
+
this.attachments = [];
|
|
218
|
+
/** 드래그 오버 상태 (시각 피드백용) */
|
|
219
|
+
this.dragOver = false;
|
|
209
220
|
/** mini action — 인라인 예시 토글 */
|
|
210
221
|
this.examplesOpen = false;
|
|
211
222
|
/** 원본 JSON 을 펼친 단계(라인:단계) — 목록은 한 줄 요약으로 훑고 필요한 것만 펼친다. */
|
|
212
223
|
this.openToolSteps = new Set();
|
|
213
224
|
/** 이미 실행을 요청한 제안 키 — 같은 카드를 두 번 눌러 되돌릴 수 없는 명령이 두 번 나가지 않게. */
|
|
214
225
|
this.sentProposals = new Set();
|
|
226
|
+
/** Proposal keys the host has reported staged. Only the host knows; see `acknowledgeProposalStaged`. */
|
|
227
|
+
this.stagedProposals = new Set();
|
|
215
228
|
/** 안내를 닫았는가 — 한 번 닫으면 이 세션에서는 다시 띄우지 않는다(잔소리 금지). */
|
|
216
229
|
this.foldNoticeDismissed = false;
|
|
217
230
|
this.busy = false;
|
|
@@ -298,10 +311,121 @@ let OxBoardAIChat = class OxBoardAIChat extends LitElement {
|
|
|
298
311
|
*/
|
|
299
312
|
this.startNewFromNotice = () => {
|
|
300
313
|
this.foldNoticeDismissed = true;
|
|
301
|
-
this.dispatchEvent(new CustomEvent('
|
|
314
|
+
this.dispatchEvent(new CustomEvent('assistant-start-new-session', { bubbles: true, composed: true }));
|
|
302
315
|
};
|
|
303
316
|
}
|
|
304
|
-
static {
|
|
317
|
+
static { OxAssistantChat_1 = this; }
|
|
318
|
+
async onAttachFiles(files) {
|
|
319
|
+
if (!files || files.length === 0)
|
|
320
|
+
return;
|
|
321
|
+
const list = Array.from(files);
|
|
322
|
+
const newAttachments = [];
|
|
323
|
+
for (const file of list) {
|
|
324
|
+
const id = 'att-' + Math.random().toString(36).substring(2, 9);
|
|
325
|
+
const url = URL.createObjectURL(file);
|
|
326
|
+
let base64;
|
|
327
|
+
try {
|
|
328
|
+
base64 = await this.readFileAsBase64(file);
|
|
329
|
+
}
|
|
330
|
+
catch (err) {
|
|
331
|
+
console.warn('Failed to read file as base64', err);
|
|
332
|
+
}
|
|
333
|
+
newAttachments.push({
|
|
334
|
+
id,
|
|
335
|
+
file,
|
|
336
|
+
name: file.name,
|
|
337
|
+
size: file.size,
|
|
338
|
+
type: file.type || 'application/octet-stream',
|
|
339
|
+
url,
|
|
340
|
+
base64
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
this.attachments = [...this.attachments, ...newAttachments];
|
|
344
|
+
}
|
|
345
|
+
readFileAsBase64(file) {
|
|
346
|
+
return new Promise((resolve, reject) => {
|
|
347
|
+
const reader = new FileReader();
|
|
348
|
+
reader.onload = () => resolve(reader.result);
|
|
349
|
+
reader.onerror = reject;
|
|
350
|
+
reader.readAsDataURL(file);
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
removeAttachment(id) {
|
|
354
|
+
const target = this.attachments.find(a => a.id === id);
|
|
355
|
+
if (target?.url) {
|
|
356
|
+
URL.revokeObjectURL(target.url);
|
|
357
|
+
}
|
|
358
|
+
this.attachments = this.attachments.filter(a => a.id !== id);
|
|
359
|
+
}
|
|
360
|
+
onComposerPaste(e) {
|
|
361
|
+
const items = e.clipboardData?.items;
|
|
362
|
+
if (!items || items.length === 0)
|
|
363
|
+
return;
|
|
364
|
+
const files = [];
|
|
365
|
+
for (let i = 0; i < items.length; i++) {
|
|
366
|
+
const item = items[i];
|
|
367
|
+
if (item.kind === 'file') {
|
|
368
|
+
const file = item.getAsFile();
|
|
369
|
+
if (file)
|
|
370
|
+
files.push(file);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
if (files.length > 0) {
|
|
374
|
+
this.onAttachFiles(files);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
onComposerDragOver(e) {
|
|
378
|
+
e.preventDefault();
|
|
379
|
+
e.stopPropagation();
|
|
380
|
+
if (!this.dragOver)
|
|
381
|
+
this.dragOver = true;
|
|
382
|
+
}
|
|
383
|
+
onComposerDragLeave(e) {
|
|
384
|
+
e.preventDefault();
|
|
385
|
+
e.stopPropagation();
|
|
386
|
+
const currentTarget = e.currentTarget;
|
|
387
|
+
const relatedTarget = e.relatedTarget;
|
|
388
|
+
if (!currentTarget.contains(relatedTarget)) {
|
|
389
|
+
this.dragOver = false;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
onComposerDrop(e) {
|
|
393
|
+
e.preventDefault();
|
|
394
|
+
e.stopPropagation();
|
|
395
|
+
this.dragOver = false;
|
|
396
|
+
if (e.dataTransfer?.files?.length) {
|
|
397
|
+
this.onAttachFiles(e.dataTransfer.files);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* The host reports that it put this candidate somewhere the person can look at it.
|
|
402
|
+
*
|
|
403
|
+
* Staging happens outside this component — a dock catches `assistant-proposal-preview`, hands
|
|
404
|
+
* the candidate to a viewer, and only that host knows whether it worked, or whether it has a
|
|
405
|
+
* viewer at all. So the card says nothing until the host calls this, and it then says it in the
|
|
406
|
+
* words the host registered (`chatDefaults.stagedNoticeKey`).
|
|
407
|
+
*
|
|
408
|
+
* Safe to call for a candidate the card never showed; the key simply never matches.
|
|
409
|
+
*/
|
|
410
|
+
acknowledgeProposalStaged(proposal) {
|
|
411
|
+
/*
|
|
412
|
+
Silence has two meanings and they are not the same defect. A host that never calls this is
|
|
413
|
+
telling us it does not know, and drawing nothing is right. A host that calls it without
|
|
414
|
+
registering `stagedNoticeKey` meant to say something and left out the words -- staying quiet
|
|
415
|
+
about that reads to whoever wired it as "the badge just doesn't appear here".
|
|
416
|
+
|
|
417
|
+
The screen still shows nothing either way. There is no sentence to show, and inventing one is
|
|
418
|
+
what this whole correction removed.
|
|
419
|
+
*/
|
|
420
|
+
if (!chatDefaults.stagedNoticeKey && !OxAssistantChat_1.warnedMissingStagedNotice) {
|
|
421
|
+
OxAssistantChat_1.warnedMissingStagedNotice = true;
|
|
422
|
+
console.warn('[assistant-chat] a host reported a proposal staged but registered no `stagedNoticeKey`, ' +
|
|
423
|
+
'so the card can say nothing. Pass one to `registerChatDefaults` from the host.');
|
|
424
|
+
}
|
|
425
|
+
this.stagedProposals = new Set(this.stagedProposals).add(this.proposalKey(proposal));
|
|
426
|
+
}
|
|
427
|
+
/** Once per page: the miss is a wiring mistake, and repeating it per candidate buries it. */
|
|
428
|
+
static { this.warnedMissingStagedNotice = false; }
|
|
305
429
|
/** 현재 로그인 사용자 email — 그룹챗에서 내 메시지 vs 타인 메시지 구분.
|
|
306
430
|
* email 을 쓰는 이유: /auth/profile 이 항상 내려주는 로그인 식별자이고(비어 있지 않다),
|
|
307
431
|
* 내부 관리키(User.id)를 클라이언트 판정에 의존하지 않기 위함. */
|
|
@@ -1092,6 +1216,63 @@ let OxBoardAIChat = class OxBoardAIChat extends LitElement {
|
|
|
1092
1216
|
.proposal.sent {
|
|
1093
1217
|
border-left-color: var(--md-sys-color-outline, #94a3b8);
|
|
1094
1218
|
}
|
|
1219
|
+
.proposal .staged-badge {
|
|
1220
|
+
display: inline-flex;
|
|
1221
|
+
align-items: center;
|
|
1222
|
+
gap: 3px;
|
|
1223
|
+
padding: 3px 8px;
|
|
1224
|
+
border-radius: 999px;
|
|
1225
|
+
background: rgba(15, 118, 110, 0.1);
|
|
1226
|
+
color: var(--md-sys-color-primary, #0f766e);
|
|
1227
|
+
font-size: 11px;
|
|
1228
|
+
font-weight: 600;
|
|
1229
|
+
flex-shrink: 0;
|
|
1230
|
+
}
|
|
1231
|
+
.proposal .staged-badge md-icon {
|
|
1232
|
+
--md-icon-size: 13px;
|
|
1233
|
+
color: inherit;
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
.proposal-choices {
|
|
1237
|
+
display: flex;
|
|
1238
|
+
flex-wrap: wrap;
|
|
1239
|
+
gap: 6px;
|
|
1240
|
+
margin-top: 6px;
|
|
1241
|
+
padding: 6px 8px;
|
|
1242
|
+
background: var(--md-sys-color-surface-container-lowest, #ffffff);
|
|
1243
|
+
border: 1px solid var(--md-sys-color-outline-variant, #e2e8f0);
|
|
1244
|
+
border-radius: 8px;
|
|
1245
|
+
}
|
|
1246
|
+
.proposal-choices .choice-chip {
|
|
1247
|
+
display: inline-flex;
|
|
1248
|
+
align-items: center;
|
|
1249
|
+
gap: 4px;
|
|
1250
|
+
padding: 4px 9px;
|
|
1251
|
+
border-radius: 999px;
|
|
1252
|
+
border: 1px solid var(--md-sys-color-outline-variant, #cbd5e1);
|
|
1253
|
+
background: var(--md-sys-color-surface-container-low, #f8fafc);
|
|
1254
|
+
color: var(--md-sys-color-on-surface, #1e293b);
|
|
1255
|
+
font-family: inherit;
|
|
1256
|
+
font-size: 11px;
|
|
1257
|
+
font-weight: 550;
|
|
1258
|
+
cursor: pointer;
|
|
1259
|
+
transition: all 0.14s ease-in-out;
|
|
1260
|
+
}
|
|
1261
|
+
.proposal-choices .choice-chip:hover {
|
|
1262
|
+
background: var(--md-sys-color-surface-container-high, #e2e8f0);
|
|
1263
|
+
border-color: var(--md-sys-color-primary, #0f766e);
|
|
1264
|
+
color: var(--md-sys-color-primary, #0f766e);
|
|
1265
|
+
}
|
|
1266
|
+
.proposal-choices .choice-chip.primary {
|
|
1267
|
+
background: var(--md-sys-color-primary-container, #ccfbf1);
|
|
1268
|
+
color: var(--md-sys-color-on-primary-container, #0f766e);
|
|
1269
|
+
border-color: var(--md-sys-color-primary, #0f766e);
|
|
1270
|
+
font-weight: 650;
|
|
1271
|
+
}
|
|
1272
|
+
.proposal-choices .choice-chip md-icon {
|
|
1273
|
+
--md-icon-size: 13px;
|
|
1274
|
+
color: inherit;
|
|
1275
|
+
}
|
|
1095
1276
|
|
|
1096
1277
|
/* ── 접지 경고 — 근거에 없는 대상을 지목한 답 ───── */
|
|
1097
1278
|
.grounding-warning {
|
|
@@ -1394,10 +1575,156 @@ let OxBoardAIChat = class OxBoardAIChat extends LitElement {
|
|
|
1394
1575
|
|
|
1395
1576
|
/* ── Composer (actions + input 통합 영역) ──────────── */
|
|
1396
1577
|
.composer {
|
|
1578
|
+
position: relative;
|
|
1397
1579
|
border-top: 1px solid var(--md-sys-color-outline-variant, #f1f5f9);
|
|
1398
1580
|
background: var(--md-sys-color-surface, #ffffff);
|
|
1399
1581
|
display: flex;
|
|
1400
1582
|
flex-direction: column;
|
|
1583
|
+
transition: background 0.15s, border-color 0.15s;
|
|
1584
|
+
}
|
|
1585
|
+
.composer.drag-over {
|
|
1586
|
+
background: var(--md-sys-color-surface-container, #f1f5f9);
|
|
1587
|
+
border-top-color: var(--md-sys-color-primary, #0284c7);
|
|
1588
|
+
}
|
|
1589
|
+
.drag-drop-overlay {
|
|
1590
|
+
position: absolute;
|
|
1591
|
+
top: 0;
|
|
1592
|
+
left: 0;
|
|
1593
|
+
right: 0;
|
|
1594
|
+
bottom: 0;
|
|
1595
|
+
background: rgba(255, 255, 255, 0.94);
|
|
1596
|
+
backdrop-filter: blur(2px);
|
|
1597
|
+
z-index: 10;
|
|
1598
|
+
display: flex;
|
|
1599
|
+
flex-direction: column;
|
|
1600
|
+
align-items: center;
|
|
1601
|
+
justify-content: center;
|
|
1602
|
+
gap: 6px;
|
|
1603
|
+
border: 2px dashed var(--md-sys-color-primary, #0284c7);
|
|
1604
|
+
border-radius: 4px;
|
|
1605
|
+
color: var(--md-sys-color-primary, #0284c7);
|
|
1606
|
+
font-size: 13px;
|
|
1607
|
+
font-weight: 500;
|
|
1608
|
+
pointer-events: none;
|
|
1609
|
+
}
|
|
1610
|
+
.drag-drop-overlay md-icon {
|
|
1611
|
+
--md-icon-size: 28px;
|
|
1612
|
+
}
|
|
1613
|
+
.attachment-strip {
|
|
1614
|
+
display: flex;
|
|
1615
|
+
flex-wrap: wrap;
|
|
1616
|
+
gap: 6px;
|
|
1617
|
+
padding: 6px 14px 2px;
|
|
1618
|
+
max-height: 120px;
|
|
1619
|
+
overflow-y: auto;
|
|
1620
|
+
}
|
|
1621
|
+
.attachment-chip {
|
|
1622
|
+
display: flex;
|
|
1623
|
+
align-items: center;
|
|
1624
|
+
gap: 6px;
|
|
1625
|
+
background: var(--md-sys-color-surface-container, #f1f5f9);
|
|
1626
|
+
border: 1px solid var(--md-sys-color-outline-variant, #e2e8f0);
|
|
1627
|
+
border-radius: 8px;
|
|
1628
|
+
padding: 3px 6px 3px 4px;
|
|
1629
|
+
max-width: 220px;
|
|
1630
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
1631
|
+
}
|
|
1632
|
+
.attachment-thumb {
|
|
1633
|
+
width: 28px;
|
|
1634
|
+
height: 28px;
|
|
1635
|
+
object-fit: cover;
|
|
1636
|
+
border-radius: 4px;
|
|
1637
|
+
flex: none;
|
|
1638
|
+
}
|
|
1639
|
+
.attachment-icon {
|
|
1640
|
+
--md-icon-size: 20px;
|
|
1641
|
+
color: var(--md-sys-color-primary, #0284c7);
|
|
1642
|
+
flex: none;
|
|
1643
|
+
}
|
|
1644
|
+
.attachment-meta {
|
|
1645
|
+
display: flex;
|
|
1646
|
+
flex-direction: column;
|
|
1647
|
+
min-width: 0;
|
|
1648
|
+
flex: 1;
|
|
1649
|
+
}
|
|
1650
|
+
.attachment-name {
|
|
1651
|
+
font-size: 11px;
|
|
1652
|
+
font-weight: 500;
|
|
1653
|
+
color: var(--md-sys-color-on-surface, #0f172a);
|
|
1654
|
+
overflow: hidden;
|
|
1655
|
+
text-overflow: ellipsis;
|
|
1656
|
+
white-space: nowrap;
|
|
1657
|
+
}
|
|
1658
|
+
.attachment-size {
|
|
1659
|
+
font-size: 9px;
|
|
1660
|
+
color: var(--md-sys-color-outline, #64748b);
|
|
1661
|
+
}
|
|
1662
|
+
.attachment-remove {
|
|
1663
|
+
all: unset;
|
|
1664
|
+
display: flex;
|
|
1665
|
+
align-items: center;
|
|
1666
|
+
justify-content: center;
|
|
1667
|
+
width: 18px;
|
|
1668
|
+
height: 18px;
|
|
1669
|
+
border-radius: 50%;
|
|
1670
|
+
cursor: pointer;
|
|
1671
|
+
color: var(--md-sys-color-outline, #64748b);
|
|
1672
|
+
transition: background 0.15s, color 0.15s;
|
|
1673
|
+
flex: none;
|
|
1674
|
+
}
|
|
1675
|
+
.attachment-remove:hover {
|
|
1676
|
+
background: var(--md-sys-color-surface-container-highest, #cbd5e1);
|
|
1677
|
+
color: var(--md-sys-color-error, #ef4444);
|
|
1678
|
+
}
|
|
1679
|
+
.attachment-remove md-icon {
|
|
1680
|
+
--md-icon-size: 14px;
|
|
1681
|
+
}
|
|
1682
|
+
.msg-attachments {
|
|
1683
|
+
display: flex;
|
|
1684
|
+
flex-wrap: wrap;
|
|
1685
|
+
gap: 8px;
|
|
1686
|
+
margin-top: 8px;
|
|
1687
|
+
}
|
|
1688
|
+
.msg-attachment-img-wrap {
|
|
1689
|
+
border-radius: 8px;
|
|
1690
|
+
overflow: hidden;
|
|
1691
|
+
border: 1px solid var(--md-sys-color-outline-variant, #e2e8f0);
|
|
1692
|
+
background: var(--md-sys-color-surface-container-lowest, #ffffff);
|
|
1693
|
+
max-width: 240px;
|
|
1694
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
|
1695
|
+
display: flex;
|
|
1696
|
+
flex-direction: column;
|
|
1697
|
+
}
|
|
1698
|
+
.msg-attachment-img-wrap img {
|
|
1699
|
+
max-width: 100%;
|
|
1700
|
+
max-height: 160px;
|
|
1701
|
+
object-fit: cover;
|
|
1702
|
+
display: block;
|
|
1703
|
+
}
|
|
1704
|
+
.msg-attachment-label {
|
|
1705
|
+
padding: 4px 8px;
|
|
1706
|
+
font-size: 10px;
|
|
1707
|
+
color: var(--md-sys-color-on-surface-variant, #64748b);
|
|
1708
|
+
background: var(--md-sys-color-surface-container, #f8fafc);
|
|
1709
|
+
overflow: hidden;
|
|
1710
|
+
text-overflow: ellipsis;
|
|
1711
|
+
white-space: nowrap;
|
|
1712
|
+
border-top: 1px solid var(--md-sys-color-outline-variant, #f1f5f9);
|
|
1713
|
+
}
|
|
1714
|
+
.msg-attachment-file-chip {
|
|
1715
|
+
display: flex;
|
|
1716
|
+
align-items: center;
|
|
1717
|
+
gap: 6px;
|
|
1718
|
+
padding: 6px 10px;
|
|
1719
|
+
border-radius: 8px;
|
|
1720
|
+
background: var(--md-sys-color-surface-container, #f8fafc);
|
|
1721
|
+
border: 1px solid var(--md-sys-color-outline-variant, #e2e8f0);
|
|
1722
|
+
font-size: 11px;
|
|
1723
|
+
color: var(--md-sys-color-on-surface, #0f172a);
|
|
1724
|
+
}
|
|
1725
|
+
.msg-attachment-file-chip md-icon {
|
|
1726
|
+
--md-icon-size: 18px;
|
|
1727
|
+
color: var(--md-sys-color-primary, #0284c7);
|
|
1401
1728
|
}
|
|
1402
1729
|
|
|
1403
1730
|
/* ── Mini action row (메시지 시작 후) ──────────────── */
|
|
@@ -1824,6 +2151,25 @@ let OxBoardAIChat = class OxBoardAIChat extends LitElement {
|
|
|
1824
2151
|
>${content}</span
|
|
1825
2152
|
>`
|
|
1826
2153
|
: content}
|
|
2154
|
+
${line.attachments && line.attachments.length > 0
|
|
2155
|
+
? html `
|
|
2156
|
+
<div class="msg-attachments">
|
|
2157
|
+
${line.attachments.map(att => att.type?.startsWith('image/') || att.url?.startsWith('data:image/') || att.base64
|
|
2158
|
+
? html `
|
|
2159
|
+
<div class="msg-attachment-img-wrap" title=${att.name}>
|
|
2160
|
+
<img src=${att.url || att.base64} alt=${att.name} />
|
|
2161
|
+
<span class="msg-attachment-label">${att.name}</span>
|
|
2162
|
+
</div>
|
|
2163
|
+
`
|
|
2164
|
+
: html `
|
|
2165
|
+
<div class="msg-attachment-file-chip" title=${att.name}>
|
|
2166
|
+
<md-icon>description</md-icon>
|
|
2167
|
+
<span>${att.name}</span>
|
|
2168
|
+
</div>
|
|
2169
|
+
`)}
|
|
2170
|
+
</div>
|
|
2171
|
+
`
|
|
2172
|
+
: nothing}
|
|
1827
2173
|
${line.patchId
|
|
1828
2174
|
? html `
|
|
1829
2175
|
<div class="summary ${this.revertedPatchIds.has(line.patchId) ? 'reverted' : ''}">
|
|
@@ -1874,11 +2220,47 @@ let OxBoardAIChat = class OxBoardAIChat extends LitElement {
|
|
|
1874
2220
|
`
|
|
1875
2221
|
: nothing}
|
|
1876
2222
|
${this.renderFoldNotice()}
|
|
1877
|
-
<div
|
|
1878
|
-
${
|
|
2223
|
+
<div
|
|
2224
|
+
class="composer ${this.dragOver ? 'drag-over' : ''}"
|
|
2225
|
+
@dragover=${(e) => this.onComposerDragOver(e)}
|
|
2226
|
+
@dragleave=${(e) => this.onComposerDragLeave(e)}
|
|
2227
|
+
@drop=${(e) => this.onComposerDrop(e)}
|
|
2228
|
+
@paste=${(e) => this.onComposerPaste(e)}>
|
|
2229
|
+
${this.dragOver
|
|
2230
|
+
? html `
|
|
2231
|
+
<div class="drag-drop-overlay">
|
|
2232
|
+
<md-icon>cloud_upload</md-icon>
|
|
2233
|
+
<span>${i18next.t('ai-assistant.text.drop-files-here', { defaultValue: '여기에 이미지나 파일을 놓으세요' })}</span>
|
|
2234
|
+
</div>
|
|
2235
|
+
`
|
|
2236
|
+
: nothing}
|
|
2237
|
+
<div class="actions-row">
|
|
2238
|
+
<input
|
|
2239
|
+
id="chat-file-input"
|
|
2240
|
+
type="file"
|
|
2241
|
+
multiple
|
|
2242
|
+
accept="image/*,.json,.txt,.csv"
|
|
2243
|
+
style="display: none"
|
|
2244
|
+
@change=${(e) => {
|
|
2245
|
+
const input = e.target;
|
|
2246
|
+
if (input.files?.length) {
|
|
2247
|
+
this.onAttachFiles(input.files);
|
|
2248
|
+
input.value = '';
|
|
2249
|
+
}
|
|
2250
|
+
}}
|
|
2251
|
+
/>
|
|
2252
|
+
<button
|
|
2253
|
+
type="button"
|
|
2254
|
+
class="action"
|
|
2255
|
+
@click=${() => this.renderRoot.querySelector('#chat-file-input')?.click()}
|
|
2256
|
+
title=${i18next.t('ai-assistant.tooltip.attach-file', { defaultValue: '이미지 또는 파일 첨부 (클립보드 붙여넣기·드래그앤드롭 지원)' })}>
|
|
2257
|
+
<md-icon>attach_file</md-icon>
|
|
2258
|
+
${i18next.t('ai-assistant.button.attach', { defaultValue: '첨부' })}
|
|
2259
|
+
</button>
|
|
2260
|
+
${hasMessages
|
|
1879
2261
|
? html `
|
|
1880
|
-
<div class="actions-row">
|
|
1881
2262
|
<button
|
|
2263
|
+
type="button"
|
|
1882
2264
|
class="action"
|
|
1883
2265
|
@click=${() => (this.examplesOpen = !this.examplesOpen)}
|
|
1884
2266
|
title=${i18next.t('ai-assistant.text.show-examples-tooltip')}>
|
|
@@ -1887,8 +2269,32 @@ let OxBoardAIChat = class OxBoardAIChat extends LitElement {
|
|
|
1887
2269
|
? i18next.t('ai-assistant.button.close')
|
|
1888
2270
|
: i18next.t('ai-assistant.button.examples')}
|
|
1889
2271
|
</button>
|
|
2272
|
+
`
|
|
2273
|
+
: nothing}
|
|
2274
|
+
</div>
|
|
2275
|
+
${this.examplesOpen ? this.renderInlineExamples() : nothing}
|
|
2276
|
+
${this.attachments.length > 0
|
|
2277
|
+
? html `
|
|
2278
|
+
<div class="attachment-strip">
|
|
2279
|
+
${this.attachments.map(att => html `
|
|
2280
|
+
<div class="attachment-chip" title=${att.name}>
|
|
2281
|
+
${att.type.startsWith('image/')
|
|
2282
|
+
? html `<img class="attachment-thumb" src=${att.url} alt=${att.name} />`
|
|
2283
|
+
: html `<md-icon class="attachment-icon">description</md-icon>`}
|
|
2284
|
+
<div class="attachment-meta">
|
|
2285
|
+
<span class="attachment-name">${att.name}</span>
|
|
2286
|
+
<span class="attachment-size">${formatFileSize(att.size)}</span>
|
|
2287
|
+
</div>
|
|
2288
|
+
<button
|
|
2289
|
+
type="button"
|
|
2290
|
+
class="attachment-remove"
|
|
2291
|
+
title=${i18next.t('ai-assistant.button.remove-attachment', { defaultValue: '첨부 삭제' })}
|
|
2292
|
+
@click=${() => this.removeAttachment(att.id)}>
|
|
2293
|
+
<md-icon>close</md-icon>
|
|
2294
|
+
</button>
|
|
2295
|
+
</div>
|
|
2296
|
+
`)}
|
|
1890
2297
|
</div>
|
|
1891
|
-
${this.examplesOpen ? this.renderInlineExamples() : nothing}
|
|
1892
2298
|
`
|
|
1893
2299
|
: nothing}
|
|
1894
2300
|
<div class="input-row">
|
|
@@ -1925,7 +2331,7 @@ let OxBoardAIChat = class OxBoardAIChat extends LitElement {
|
|
|
1925
2331
|
: nothing}
|
|
1926
2332
|
</div>
|
|
1927
2333
|
<button
|
|
1928
|
-
?disabled=${this.busy || !this.input.trim()}
|
|
2334
|
+
?disabled=${this.busy || (!this.input.trim() && this.attachments.length === 0)}
|
|
1929
2335
|
@click=${this.send}
|
|
1930
2336
|
title=${i18next.t('ai-assistant.text.send-tooltip')}>
|
|
1931
2337
|
${this.busy
|
|
@@ -2200,7 +2606,7 @@ let OxBoardAIChat = class OxBoardAIChat extends LitElement {
|
|
|
2200
2606
|
get exampleGroups() {
|
|
2201
2607
|
if (this.examples?.length)
|
|
2202
2608
|
return this.examples;
|
|
2203
|
-
return
|
|
2609
|
+
return OxAssistantChat_1.EXAMPLE_GROUPS.map(group => ({
|
|
2204
2610
|
label: i18next.t(group.labelKey),
|
|
2205
2611
|
items: group.itemKeys.map(key => i18next.t(key))
|
|
2206
2612
|
}));
|
|
@@ -2461,13 +2867,26 @@ let OxBoardAIChat = class OxBoardAIChat extends LitElement {
|
|
|
2461
2867
|
${items.map(p => {
|
|
2462
2868
|
const key = this.proposalKey(p);
|
|
2463
2869
|
const sent = this.sentProposals.has(key);
|
|
2870
|
+
/*
|
|
2871
|
+
Follow-up chips are the host's words, never this component's. The fallback that used
|
|
2872
|
+
to live here named a 3D modeller's operations in hardcoded Korean, and it reached the
|
|
2873
|
+
plant and twin chats too.
|
|
2874
|
+
*/
|
|
2875
|
+
const rawChoices = Array.isArray(p.choices) ? p.choices : (chatDefaults.proposalChoices ?? []);
|
|
2464
2876
|
return html `
|
|
2465
2877
|
<div class="proposal ${sent ? 'sent' : ''}">
|
|
2466
|
-
<md-icon
|
|
2878
|
+
<md-icon>${p.icon || (p.source ? 'view_in_ar' : 'bolt')}</md-icon>
|
|
2467
2879
|
<span class="pbody">
|
|
2468
2880
|
<span class="plabel">${p.label || p.command}</span>
|
|
2469
2881
|
${p.reason ? html `<span class="preason">${p.reason}</span>` : nothing}
|
|
2470
2882
|
</span>
|
|
2883
|
+
${ /*
|
|
2884
|
+
The run button and the follow-up chips answer different questions — "is there
|
|
2885
|
+
something to apply" and "what else could I ask for" — and they used to share one
|
|
2886
|
+
ternary on `rawChoices.length`. A proposal that carried chips lost its button, so
|
|
2887
|
+
the one action the card exists for became unreachable while the model kept
|
|
2888
|
+
telling people to press it.
|
|
2889
|
+
*/''}
|
|
2471
2890
|
<button
|
|
2472
2891
|
class="run"
|
|
2473
2892
|
?disabled=${sent}
|
|
@@ -2475,12 +2894,63 @@ let OxBoardAIChat = class OxBoardAIChat extends LitElement {
|
|
|
2475
2894
|
${sent ? i18next.t('ai-assistant.text.proposal-sent', { defaultValue: '실행 요청됨' })
|
|
2476
2895
|
: i18next.t('ai-assistant.button.run-proposal', { defaultValue: '실행' })}
|
|
2477
2896
|
</button>
|
|
2897
|
+
${ /*
|
|
2898
|
+
Drawn only where the host has said it staged this candidate, in the host's own
|
|
2899
|
+
words. Not knowing is not a claim: with no word from the host, nothing is drawn.
|
|
2900
|
+
This badge used to read "there are chips" as "the model is in the 3D viewer" and
|
|
2901
|
+
say so, in a component that plant and twin also use.
|
|
2902
|
+
*/''}
|
|
2903
|
+
${this.stagedProposals.has(key) && chatDefaults.stagedNoticeKey ? html `
|
|
2904
|
+
<span class="staged-badge">
|
|
2905
|
+
<md-icon>check_circle</md-icon>
|
|
2906
|
+
<span>${i18next.t(chatDefaults.stagedNoticeKey)}</span>
|
|
2907
|
+
</span>
|
|
2908
|
+
` : nothing}
|
|
2478
2909
|
</div>
|
|
2910
|
+
${rawChoices.length ? html `
|
|
2911
|
+
<div class="proposal-choices" role="group" aria-label="대화 선택지">
|
|
2912
|
+
${rawChoices.map((c) => html `
|
|
2913
|
+
<button
|
|
2914
|
+
class="choice-chip ${c.primary ? 'primary' : ''}"
|
|
2915
|
+
title=${c.prompt || c.label}
|
|
2916
|
+
@click=${() => this.onChoiceClick(c, p, key)}>
|
|
2917
|
+
${c.icon ? html `<md-icon>${c.icon}</md-icon>` : nothing}
|
|
2918
|
+
<span>${c.label}</span>
|
|
2919
|
+
</button>
|
|
2920
|
+
`)}
|
|
2921
|
+
</div>
|
|
2922
|
+
` : nothing}
|
|
2479
2923
|
`;
|
|
2480
2924
|
})}
|
|
2481
2925
|
</div>
|
|
2482
2926
|
`;
|
|
2483
2927
|
}
|
|
2928
|
+
onChoiceClick(choice, proposal, key) {
|
|
2929
|
+
if (choice.action === 'save') {
|
|
2930
|
+
this.dispatchEvent(new CustomEvent('assistant-choice', {
|
|
2931
|
+
detail: { action: 'save', choice, proposal, sessionId: this.sessionId },
|
|
2932
|
+
bubbles: true,
|
|
2933
|
+
composed: true
|
|
2934
|
+
}));
|
|
2935
|
+
this.executeProposal(proposal, key);
|
|
2936
|
+
return;
|
|
2937
|
+
}
|
|
2938
|
+
if (choice.action === 'prompt' && choice.prompt) {
|
|
2939
|
+
this.input = choice.prompt;
|
|
2940
|
+
this.dispatchEvent(new CustomEvent('assistant-choice', {
|
|
2941
|
+
detail: { action: 'prompt', choice, proposal, sessionId: this.sessionId },
|
|
2942
|
+
bubbles: true,
|
|
2943
|
+
composed: true
|
|
2944
|
+
}));
|
|
2945
|
+
void this.send();
|
|
2946
|
+
return;
|
|
2947
|
+
}
|
|
2948
|
+
this.dispatchEvent(new CustomEvent('assistant-choice', {
|
|
2949
|
+
detail: { action: choice.action || 'custom', choice, proposal, sessionId: this.sessionId },
|
|
2950
|
+
bubbles: true,
|
|
2951
|
+
composed: true
|
|
2952
|
+
}));
|
|
2953
|
+
}
|
|
2484
2954
|
/**
|
|
2485
2955
|
* 제안 식별 키 — 같은 조치를 두 번 실행하지 않도록 **효과**(명령·대상·인자)로만 만든다.
|
|
2486
2956
|
*
|
|
@@ -2512,7 +2982,7 @@ let OxBoardAIChat = class OxBoardAIChat extends LitElement {
|
|
|
2512
2982
|
*/
|
|
2513
2983
|
executeProposal(p, key) {
|
|
2514
2984
|
this.sentProposals = new Set(this.sentProposals).add(key);
|
|
2515
|
-
this.dispatchEvent(new CustomEvent('
|
|
2985
|
+
this.dispatchEvent(new CustomEvent('assistant-proposal-execute', {
|
|
2516
2986
|
detail: { proposal: p, sessionId: this.sessionId },
|
|
2517
2987
|
bubbles: true,
|
|
2518
2988
|
composed: true
|
|
@@ -2777,8 +3247,15 @@ let OxBoardAIChat = class OxBoardAIChat extends LitElement {
|
|
|
2777
3247
|
}
|
|
2778
3248
|
async send() {
|
|
2779
3249
|
const text = this.input.trim();
|
|
2780
|
-
|
|
3250
|
+
const attachmentsToSend = [...this.attachments];
|
|
3251
|
+
if ((!text && attachmentsToSend.length === 0) || this.busy)
|
|
2781
3252
|
return;
|
|
3253
|
+
this.attachments = [];
|
|
3254
|
+
const promptText = text || (attachmentsToSend.length > 0
|
|
3255
|
+
? (attachmentsToSend[0].type.startsWith('image/')
|
|
3256
|
+
? '첨부된 이미지를 참고하여 제안해 주세요.'
|
|
3257
|
+
: '첨부된 파일을 확인해 주세요.')
|
|
3258
|
+
: '');
|
|
2782
3259
|
if (!this.sessionId && this.prepareSession) {
|
|
2783
3260
|
this.busy = true;
|
|
2784
3261
|
try {
|
|
@@ -2810,22 +3287,34 @@ let OxBoardAIChat = class OxBoardAIChat extends LitElement {
|
|
|
2810
3287
|
// 등장하는 것만 추출 — 지운 토큰 제외. inline 마커로 content 에 주입.
|
|
2811
3288
|
const mentions = [];
|
|
2812
3289
|
for (const [token, refid] of this.pickedMentions.entries()) {
|
|
2813
|
-
if (
|
|
3290
|
+
if (promptText.includes(`#${token}`))
|
|
2814
3291
|
mentions.push({ token, refid });
|
|
2815
3292
|
}
|
|
2816
3293
|
const userMentions = [];
|
|
2817
3294
|
for (const [token, userId] of this.pickedUserMentions.entries()) {
|
|
2818
|
-
if (
|
|
3295
|
+
if (promptText.includes(`@${token}`))
|
|
2819
3296
|
userMentions.push({ token, userId });
|
|
2820
3297
|
}
|
|
2821
|
-
let enrichedContent = injectMentionRefids(
|
|
3298
|
+
let enrichedContent = injectMentionRefids(promptText, mentions);
|
|
2822
3299
|
enrichedContent = injectMentionUserIds(enrichedContent, userMentions);
|
|
2823
3300
|
// optimistic 라인에 임시 핸들 — 방송 에코와의 reconcile 을 index 비의존으로.
|
|
2824
3301
|
const userLocalId = `local-${++this._localSeq}-u`;
|
|
2825
3302
|
const asstLocalId = `local-${++this._localSeq}-a`;
|
|
2826
3303
|
this.lines = [
|
|
2827
3304
|
...this.lines,
|
|
2828
|
-
{
|
|
3305
|
+
{
|
|
3306
|
+
role: 'user',
|
|
3307
|
+
content: enrichedContent,
|
|
3308
|
+
attachments: attachmentsToSend.map(a => ({
|
|
3309
|
+
name: a.name,
|
|
3310
|
+
size: a.size,
|
|
3311
|
+
type: a.type,
|
|
3312
|
+
url: a.url,
|
|
3313
|
+
base64: a.base64
|
|
3314
|
+
})),
|
|
3315
|
+
_localId: userLocalId,
|
|
3316
|
+
senderEmail: this._myEmail
|
|
3317
|
+
}
|
|
2829
3318
|
];
|
|
2830
3319
|
this.input = '';
|
|
2831
3320
|
this.busy = true;
|
|
@@ -2833,6 +3322,24 @@ let OxBoardAIChat = class OxBoardAIChat extends LitElement {
|
|
|
2833
3322
|
// 가짜 pending 응답 표시 (UX 부드럽게)
|
|
2834
3323
|
this.lines = [...this.lines, { role: 'assistant', content: '', pending: true, _localId: asstLocalId }];
|
|
2835
3324
|
try {
|
|
3325
|
+
if (attachmentsToSend.length > 0) {
|
|
3326
|
+
requestContext.hostContext = {
|
|
3327
|
+
...requestContext.hostContext,
|
|
3328
|
+
attachments: attachmentsToSend.map(a => ({
|
|
3329
|
+
name: a.name,
|
|
3330
|
+
size: a.size,
|
|
3331
|
+
mediaType: a.type,
|
|
3332
|
+
data: a.base64
|
|
3333
|
+
})),
|
|
3334
|
+
image: attachmentsToSend.find(a => a.type.startsWith('image/'))
|
|
3335
|
+
? {
|
|
3336
|
+
name: attachmentsToSend.find(a => a.type.startsWith('image/')).name,
|
|
3337
|
+
mediaType: attachmentsToSend.find(a => a.type.startsWith('image/')).type,
|
|
3338
|
+
data: attachmentsToSend.find(a => a.type.startsWith('image/')).base64
|
|
3339
|
+
}
|
|
3340
|
+
: undefined
|
|
3341
|
+
};
|
|
3342
|
+
}
|
|
2836
3343
|
// LLM 으로 보낼 history — user/assistant 만 (system 은 백엔드가 자동 합류).
|
|
2837
3344
|
// pending placeholder 와 system 은 제외 (index 비의존 — 방송 append 와 무관).
|
|
2838
3345
|
const history = this.lines
|
|
@@ -2895,6 +3402,18 @@ let OxBoardAIChat = class OxBoardAIChat extends LitElement {
|
|
|
2895
3402
|
proposals: Array.isArray(out.proposals) ? out.proposals : undefined,
|
|
2896
3403
|
pending: false
|
|
2897
3404
|
});
|
|
3405
|
+
// 제안 자동 프리뷰 전파 (3D 뷰어 자동 반영)
|
|
3406
|
+
if (Array.isArray(out.proposals) && out.proposals.length > 0) {
|
|
3407
|
+
for (const p of out.proposals) {
|
|
3408
|
+
if (p?.source || p?.autoStage) {
|
|
3409
|
+
this.dispatchEvent(new CustomEvent('assistant-proposal-preview', {
|
|
3410
|
+
detail: { proposal: p, sessionId: out.sessionId },
|
|
3411
|
+
bubbles: true,
|
|
3412
|
+
composed: true
|
|
3413
|
+
}));
|
|
3414
|
+
}
|
|
3415
|
+
}
|
|
3416
|
+
}
|
|
2898
3417
|
// 호스트로 patch 이벤트 전파
|
|
2899
3418
|
if (out.patch) {
|
|
2900
3419
|
this.dispatchEvent(new CustomEvent('board-edit-patch', {
|
|
@@ -2940,177 +3459,189 @@ let OxBoardAIChat = class OxBoardAIChat extends LitElement {
|
|
|
2940
3459
|
__decorate([
|
|
2941
3460
|
property({ type: String, attribute: 'session-id' }),
|
|
2942
3461
|
__metadata("design:type", String)
|
|
2943
|
-
],
|
|
3462
|
+
], OxAssistantChat.prototype, "sessionId", void 0);
|
|
2944
3463
|
__decorate([
|
|
2945
3464
|
property({ attribute: false }),
|
|
2946
3465
|
__metadata("design:type", Function)
|
|
2947
|
-
],
|
|
3466
|
+
], OxAssistantChat.prototype, "prepareSession", void 0);
|
|
2948
3467
|
__decorate([
|
|
2949
3468
|
property({ type: Array, attribute: false }),
|
|
2950
3469
|
__metadata("design:type", Array)
|
|
2951
|
-
],
|
|
3470
|
+
], OxAssistantChat.prototype, "sessions", void 0);
|
|
2952
3471
|
__decorate([
|
|
2953
3472
|
property({ type: Object }),
|
|
2954
3473
|
__metadata("design:type", Object)
|
|
2955
|
-
],
|
|
3474
|
+
], OxAssistantChat.prototype, "currentBoard", void 0);
|
|
2956
3475
|
__decorate([
|
|
2957
3476
|
property({ attribute: false }),
|
|
2958
3477
|
__metadata("design:type", Function)
|
|
2959
|
-
],
|
|
3478
|
+
], OxAssistantChat.prototype, "boardProvider", void 0);
|
|
2960
3479
|
__decorate([
|
|
2961
3480
|
property({ attribute: false }),
|
|
2962
3481
|
__metadata("design:type", Function)
|
|
2963
|
-
],
|
|
3482
|
+
], OxAssistantChat.prototype, "searchProvider", void 0);
|
|
2964
3483
|
__decorate([
|
|
2965
3484
|
property({ attribute: false }),
|
|
2966
3485
|
__metadata("design:type", Function)
|
|
2967
|
-
],
|
|
3486
|
+
], OxAssistantChat.prototype, "userProvider", void 0);
|
|
2968
3487
|
__decorate([
|
|
2969
3488
|
property({ type: Array, attribute: false }),
|
|
2970
3489
|
__metadata("design:type", Array)
|
|
2971
|
-
],
|
|
3490
|
+
], OxAssistantChat.prototype, "selectedRefids", void 0);
|
|
2972
3491
|
__decorate([
|
|
2973
3492
|
property({ type: Array, attribute: false }),
|
|
2974
3493
|
__metadata("design:type", Array)
|
|
2975
|
-
],
|
|
3494
|
+
], OxAssistantChat.prototype, "toolCategories", void 0);
|
|
2976
3495
|
__decorate([
|
|
2977
3496
|
property({ type: Object, attribute: false }),
|
|
2978
3497
|
__metadata("design:type", Object)
|
|
2979
|
-
],
|
|
3498
|
+
], OxAssistantChat.prototype, "hostContext", void 0);
|
|
2980
3499
|
__decorate([
|
|
2981
3500
|
property({ type: Boolean, attribute: 'board-tools' }),
|
|
2982
3501
|
__metadata("design:type", Object)
|
|
2983
|
-
],
|
|
3502
|
+
], OxAssistantChat.prototype, "boardTools", void 0);
|
|
2984
3503
|
__decorate([
|
|
2985
3504
|
property({ type: String, attribute: 'chat-endpoint' }),
|
|
2986
3505
|
__metadata("design:type", String)
|
|
2987
|
-
],
|
|
3506
|
+
], OxAssistantChat.prototype, "chatEndpoint", void 0);
|
|
2988
3507
|
__decorate([
|
|
2989
3508
|
property({ type: String, attribute: 'system-prompt' }),
|
|
2990
3509
|
__metadata("design:type", String)
|
|
2991
|
-
],
|
|
3510
|
+
], OxAssistantChat.prototype, "systemPrompt", void 0);
|
|
2992
3511
|
__decorate([
|
|
2993
3512
|
property({ type: Boolean, attribute: 'require-grounding-tools' }),
|
|
2994
3513
|
__metadata("design:type", Object)
|
|
2995
|
-
],
|
|
3514
|
+
], OxAssistantChat.prototype, "requireGroundingTools", void 0);
|
|
2996
3515
|
__decorate([
|
|
2997
3516
|
property({ type: Array }),
|
|
2998
3517
|
__metadata("design:type", Array)
|
|
2999
|
-
],
|
|
3518
|
+
], OxAssistantChat.prototype, "scopes", void 0);
|
|
3000
3519
|
__decorate([
|
|
3001
3520
|
property({ type: Array, attribute: 'known-types' }),
|
|
3002
3521
|
__metadata("design:type", Array)
|
|
3003
|
-
],
|
|
3522
|
+
], OxAssistantChat.prototype, "knownTypes", void 0);
|
|
3004
3523
|
__decorate([
|
|
3005
3524
|
property({ type: Array }),
|
|
3006
3525
|
__metadata("design:type", Array)
|
|
3007
|
-
],
|
|
3526
|
+
], OxAssistantChat.prototype, "categories", void 0);
|
|
3008
3527
|
__decorate([
|
|
3009
3528
|
property({ type: Array, attribute: false }),
|
|
3010
3529
|
__metadata("design:type", Array)
|
|
3011
|
-
],
|
|
3530
|
+
], OxAssistantChat.prototype, "componentSchemas", void 0);
|
|
3012
3531
|
__decorate([
|
|
3013
3532
|
property({ type: String }),
|
|
3014
3533
|
__metadata("design:type", Object)
|
|
3015
|
-
],
|
|
3534
|
+
], OxAssistantChat.prototype, "placeholder", void 0);
|
|
3016
3535
|
__decorate([
|
|
3017
3536
|
state(),
|
|
3018
3537
|
__metadata("design:type", Array)
|
|
3019
|
-
],
|
|
3538
|
+
], OxAssistantChat.prototype, "lines", void 0);
|
|
3020
3539
|
__decorate([
|
|
3021
3540
|
state(),
|
|
3022
3541
|
__metadata("design:type", Object)
|
|
3023
|
-
],
|
|
3542
|
+
], OxAssistantChat.prototype, "input", void 0);
|
|
3024
3543
|
__decorate([
|
|
3025
3544
|
property({ attribute: false }),
|
|
3026
3545
|
__metadata("design:type", String)
|
|
3027
|
-
],
|
|
3546
|
+
], OxAssistantChat.prototype, "autoAsk", void 0);
|
|
3028
3547
|
__decorate([
|
|
3029
3548
|
property(),
|
|
3030
3549
|
__metadata("design:type", String)
|
|
3031
|
-
],
|
|
3550
|
+
], OxAssistantChat.prototype, "autoAskRequestId", void 0);
|
|
3032
3551
|
__decorate([
|
|
3033
3552
|
property({ attribute: false }),
|
|
3034
3553
|
__metadata("design:type", Function)
|
|
3035
|
-
],
|
|
3554
|
+
], OxAssistantChat.prototype, "contextProvider", void 0);
|
|
3036
3555
|
__decorate([
|
|
3037
3556
|
property({ type: Object, attribute: false }),
|
|
3038
3557
|
__metadata("design:type", Object)
|
|
3039
|
-
],
|
|
3558
|
+
], OxAssistantChat.prototype, "intro", void 0);
|
|
3040
3559
|
__decorate([
|
|
3041
3560
|
property({ type: Array, attribute: false }),
|
|
3042
3561
|
__metadata("design:type", Array)
|
|
3043
|
-
],
|
|
3562
|
+
], OxAssistantChat.prototype, "examples", void 0);
|
|
3044
3563
|
__decorate([
|
|
3045
3564
|
state(),
|
|
3046
3565
|
__metadata("design:type", String)
|
|
3047
|
-
],
|
|
3566
|
+
], OxAssistantChat.prototype, "lastFailedInput", void 0);
|
|
3567
|
+
__decorate([
|
|
3568
|
+
state(),
|
|
3569
|
+
__metadata("design:type", Object)
|
|
3570
|
+
], OxAssistantChat.prototype, "revertedPatchIds", void 0);
|
|
3571
|
+
__decorate([
|
|
3572
|
+
state(),
|
|
3573
|
+
__metadata("design:type", Array)
|
|
3574
|
+
], OxAssistantChat.prototype, "attachments", void 0);
|
|
3048
3575
|
__decorate([
|
|
3049
3576
|
state(),
|
|
3050
3577
|
__metadata("design:type", Object)
|
|
3051
|
-
],
|
|
3578
|
+
], OxAssistantChat.prototype, "dragOver", void 0);
|
|
3052
3579
|
__decorate([
|
|
3053
3580
|
state(),
|
|
3054
3581
|
__metadata("design:type", Object)
|
|
3055
|
-
],
|
|
3582
|
+
], OxAssistantChat.prototype, "examplesOpen", void 0);
|
|
3056
3583
|
__decorate([
|
|
3057
3584
|
state(),
|
|
3058
3585
|
__metadata("design:type", String)
|
|
3059
|
-
],
|
|
3586
|
+
], OxAssistantChat.prototype, "toastMessage", void 0);
|
|
3060
3587
|
__decorate([
|
|
3061
3588
|
state(),
|
|
3062
3589
|
__metadata("design:type", Number)
|
|
3063
|
-
],
|
|
3590
|
+
], OxAssistantChat.prototype, "copiedIdx", void 0);
|
|
3591
|
+
__decorate([
|
|
3592
|
+
state(),
|
|
3593
|
+
__metadata("design:type", Object)
|
|
3594
|
+
], OxAssistantChat.prototype, "openToolSteps", void 0);
|
|
3064
3595
|
__decorate([
|
|
3065
3596
|
state(),
|
|
3066
3597
|
__metadata("design:type", Object)
|
|
3067
|
-
],
|
|
3598
|
+
], OxAssistantChat.prototype, "sentProposals", void 0);
|
|
3068
3599
|
__decorate([
|
|
3069
3600
|
state(),
|
|
3070
3601
|
__metadata("design:type", Object)
|
|
3071
|
-
],
|
|
3602
|
+
], OxAssistantChat.prototype, "stagedProposals", void 0);
|
|
3072
3603
|
__decorate([
|
|
3073
3604
|
state(),
|
|
3074
3605
|
__metadata("design:type", Object)
|
|
3075
|
-
],
|
|
3606
|
+
], OxAssistantChat.prototype, "historyFolded", void 0);
|
|
3076
3607
|
__decorate([
|
|
3077
3608
|
state(),
|
|
3078
3609
|
__metadata("design:type", Object)
|
|
3079
|
-
],
|
|
3610
|
+
], OxAssistantChat.prototype, "foldNoticeDismissed", void 0);
|
|
3080
3611
|
__decorate([
|
|
3081
3612
|
state(),
|
|
3082
3613
|
__metadata("design:type", Object)
|
|
3083
|
-
],
|
|
3614
|
+
], OxAssistantChat.prototype, "busy", void 0);
|
|
3084
3615
|
__decorate([
|
|
3085
3616
|
state(),
|
|
3086
3617
|
__metadata("design:type", String)
|
|
3087
|
-
],
|
|
3618
|
+
], OxAssistantChat.prototype, "errorMessage", void 0);
|
|
3088
3619
|
__decorate([
|
|
3089
3620
|
state(),
|
|
3090
3621
|
__metadata("design:type", Array)
|
|
3091
|
-
],
|
|
3622
|
+
], OxAssistantChat.prototype, "participants", void 0);
|
|
3092
3623
|
__decorate([
|
|
3093
3624
|
state(),
|
|
3094
3625
|
__metadata("design:type", Object)
|
|
3095
|
-
],
|
|
3626
|
+
], OxAssistantChat.prototype, "_presenceTick", void 0);
|
|
3096
3627
|
__decorate([
|
|
3097
3628
|
state(),
|
|
3098
3629
|
__metadata("design:type", Object)
|
|
3099
|
-
],
|
|
3630
|
+
], OxAssistantChat.prototype, "mentionOpen", void 0);
|
|
3100
3631
|
__decorate([
|
|
3101
3632
|
state(),
|
|
3102
3633
|
__metadata("design:type", Array)
|
|
3103
|
-
],
|
|
3634
|
+
], OxAssistantChat.prototype, "mentionResults", void 0);
|
|
3104
3635
|
__decorate([
|
|
3105
3636
|
state(),
|
|
3106
3637
|
__metadata("design:type", Object)
|
|
3107
|
-
],
|
|
3638
|
+
], OxAssistantChat.prototype, "mentionActiveIndex", void 0);
|
|
3108
3639
|
__decorate([
|
|
3109
3640
|
state(),
|
|
3110
3641
|
__metadata("design:type", Object)
|
|
3111
|
-
],
|
|
3112
|
-
|
|
3113
|
-
customElement('ox-
|
|
3114
|
-
],
|
|
3115
|
-
export {
|
|
3116
|
-
//# sourceMappingURL=
|
|
3642
|
+
], OxAssistantChat.prototype, "mentionOverflow", void 0);
|
|
3643
|
+
OxAssistantChat = OxAssistantChat_1 = __decorate([
|
|
3644
|
+
customElement('ox-assistant-chat')
|
|
3645
|
+
], OxAssistantChat);
|
|
3646
|
+
export { OxAssistantChat };
|
|
3647
|
+
//# sourceMappingURL=assistant-chat.js.map
|