@things-factory/ai-assistant 10.1.20 → 10.1.25
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/assistant-chat.ts +89 -18
- package/client/components/assistant-mode.test.ts +82 -0
- package/client/components/assistant-mode.ts +124 -0
- package/client/index.ts +1 -1
- package/dist-client/components/assistant-chat.d.ts +15 -4
- package/dist-client/components/assistant-chat.js +72 -18
- package/dist-client/components/assistant-chat.js.map +1 -1
- package/dist-client/components/assistant-mode.d.ts +91 -0
- package/dist-client/components/assistant-mode.js +30 -0
- package/dist-client/components/assistant-mode.js.map +1 -0
- package/dist-client/components/assistant-mode.test.d.ts +1 -0
- package/dist-client/components/assistant-mode.test.js +72 -0
- package/dist-client/components/assistant-mode.test.js.map +1 -0
- package/dist-client/index.d.ts +1 -1
- package/dist-client/index.js +1 -1
- package/dist-client/index.js.map +1 -1
- package/package.json +4 -5
- package/client/utils/board-edit-patch.ts +0 -374
- package/dist-client/tsconfig.tsbuildinfo +0 -1
- package/dist-client/utils/board-edit-patch.d.ts +0 -157
- package/dist-client/utils/board-edit-patch.js +0 -284
- package/dist-client/utils/board-edit-patch.js.map +0 -1
- package/dist-server/tsconfig.tsbuildinfo +0 -1
|
@@ -9,8 +9,8 @@ import { __decorate, __metadata } from "tslib";
|
|
|
9
9
|
* - scopes / knownTypes / categories: 도메인 컨텍스트
|
|
10
10
|
*
|
|
11
11
|
* 출력 (이벤트):
|
|
12
|
-
* - `
|
|
13
|
-
* 호스트가 받아서 보드 모델에 적용 (
|
|
12
|
+
* - `scene-edit-patch` { detail: { patch, summary, confidence, patchId } }
|
|
13
|
+
* 호스트가 받아서 보드 모델에 적용 (applyScenePatch from @operato/scene-ops).
|
|
14
14
|
* - `chat-followup` { detail: { question } }
|
|
15
15
|
*
|
|
16
16
|
* 모드 전환은 컨테이너 (워크스페이스) 의 책임. 이 컴포넌트는 자체로 풀 채팅 UX.
|
|
@@ -43,6 +43,7 @@ import { buildMentionCandidates, buildCatalogCandidates, buildSlashCandidates, b
|
|
|
43
43
|
* 뜨지 않는 것이 맞다.
|
|
44
44
|
*/
|
|
45
45
|
import { chatDefaults } from './chat-defaults.js';
|
|
46
|
+
import { isDifferentConversation, resolveConversation } from './assistant-mode.js';
|
|
46
47
|
import { availableTriggers } from './chat-triggers.js';
|
|
47
48
|
function formatFileSize(bytes) {
|
|
48
49
|
if (!bytes || bytes < 1024)
|
|
@@ -259,9 +260,13 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
|
|
|
259
260
|
* textarea 에는 @username 만 보이지만 server 한테는 정확한 userId 전달.
|
|
260
261
|
* send 시 mutation input.userMentions 로 함께 전송. */
|
|
261
262
|
this.pickedUserMentions = new Map();
|
|
262
|
-
|
|
263
|
+
/*
|
|
264
|
+
* The `@` and `/` candidates, built once per mode.
|
|
265
|
+
*
|
|
266
|
+
* These were built at field initialisation, which meant a host could not change what the
|
|
267
|
+
* panel offers without replacing the element. A mode change rebuilds them below.
|
|
268
|
+
*/
|
|
263
269
|
this.cachedCatalogCandidates = buildCatalogCandidates(chatDefaults.catalogEntries);
|
|
264
|
-
/** Default slash template 후보 캐시 — chat panel mount 시 1회 빌드 */
|
|
265
270
|
this.cachedSlashCandidates = buildSlashCandidates(chatDefaults.slashTemplates);
|
|
266
271
|
/** `@` 마지막 query 의 도메인 사용자 후보 캐시 — userProvider 응답 도착 시 갱신.
|
|
267
272
|
* query 별 캐시가 아니라 단순 "최근 결과" — async race 회피. */
|
|
@@ -417,7 +422,7 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
|
|
|
417
422
|
The screen still shows nothing either way. There is no sentence to show, and inventing one is
|
|
418
423
|
what this whole correction removed.
|
|
419
424
|
*/
|
|
420
|
-
if (!
|
|
425
|
+
if (!this.conversation.stagedNoticeKey && !OxAssistantChat_1.warnedMissingStagedNotice) {
|
|
421
426
|
OxAssistantChat_1.warnedMissingStagedNotice = true;
|
|
422
427
|
console.warn('[assistant-chat] a host reported a proposal staged but registered no `stagedNoticeKey`, ' +
|
|
423
428
|
'so the card can say nothing. Pass one to `registerChatDefaults` from the host.');
|
|
@@ -432,6 +437,24 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
|
|
|
432
437
|
get _myEmail() {
|
|
433
438
|
return auth.credential?.email;
|
|
434
439
|
}
|
|
440
|
+
/*
|
|
441
|
+
* ── What this conversation is, resolved ──────────────────────────────────────────────
|
|
442
|
+
*
|
|
443
|
+
* A mode answers first. A host that has not declared one keeps the separate properties and
|
|
444
|
+
* the global defaults it had before, which is what every consumer written before modes does.
|
|
445
|
+
*/
|
|
446
|
+
get conversation() {
|
|
447
|
+
return resolveConversation(this.mode, {
|
|
448
|
+
systemPrompt: this.systemPrompt,
|
|
449
|
+
toolCategories: this.toolCategories,
|
|
450
|
+
hostContext: this.hostContext,
|
|
451
|
+
chatEndpoint: this.chatEndpoint
|
|
452
|
+
}, chatDefaults);
|
|
453
|
+
}
|
|
454
|
+
rebuildMentionCaches() {
|
|
455
|
+
this.cachedCatalogCandidates = buildCatalogCandidates(this.conversation.catalogEntries);
|
|
456
|
+
this.cachedSlashCandidates = buildSlashCandidates(this.conversation.slashTemplates);
|
|
457
|
+
}
|
|
435
458
|
static { this.styles = [
|
|
436
459
|
// 어플리케이션 표준 스크롤바 (--scrollbar-width / --scrollbar-thumb-color 등 호스트 변수 따름)
|
|
437
460
|
ScrollbarStyles,
|
|
@@ -1938,6 +1961,33 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
|
|
|
1938
1961
|
this.input = this.autoAsk;
|
|
1939
1962
|
this.send();
|
|
1940
1963
|
}
|
|
1964
|
+
/*
|
|
1965
|
+
* The subject changed, so the conversation is over.
|
|
1966
|
+
*
|
|
1967
|
+
* A conversation about station 3 is not a conversation about station 7. Leaving the old one
|
|
1968
|
+
* on screen means the user reads an answer about a screen they are no longer looking at,
|
|
1969
|
+
* and every host that met this wrote its own guard: plant re-checked the context on each
|
|
1970
|
+
* send and threw when it had moved, twin closed its session when the anchor changed. The
|
|
1971
|
+
* mode carries an id, so the component can do it once, here.
|
|
1972
|
+
*
|
|
1973
|
+
* The host still owns `sessionId`; it hears `assistant-mode-changed` and decides whether
|
|
1974
|
+
* this subject gets a stored session of its own.
|
|
1975
|
+
*/
|
|
1976
|
+
if (changed.has('mode') && isDifferentConversation(changed.get('mode'), this.mode)) {
|
|
1977
|
+
this.rebuildMentionCaches();
|
|
1978
|
+
this.lines = [];
|
|
1979
|
+
this.pickedMentions.clear();
|
|
1980
|
+
this.pickedUserMentions.clear();
|
|
1981
|
+
this.cachedUserCandidates = [];
|
|
1982
|
+
this.errorMessage = undefined;
|
|
1983
|
+
this.input = '';
|
|
1984
|
+
this._seenMessageIds.clear();
|
|
1985
|
+
this.dispatchEvent(new CustomEvent('assistant-mode-changed', {
|
|
1986
|
+
detail: { mode: this.mode },
|
|
1987
|
+
bubbles: true,
|
|
1988
|
+
composed: true
|
|
1989
|
+
}));
|
|
1990
|
+
}
|
|
1941
1991
|
if (changed.has('sessionId') && this.adoptingSession) {
|
|
1942
1992
|
this.adoptingSession = false;
|
|
1943
1993
|
this._startPresence();
|
|
@@ -2530,7 +2580,7 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
|
|
|
2530
2580
|
}
|
|
2531
2581
|
}
|
|
2532
2582
|
dispatchActions(actions) {
|
|
2533
|
-
this.dispatchEvent(new CustomEvent('
|
|
2583
|
+
this.dispatchEvent(new CustomEvent('scene-action-execute', {
|
|
2534
2584
|
detail: { actions, sessionId: this.sessionId },
|
|
2535
2585
|
bubbles: true,
|
|
2536
2586
|
composed: true
|
|
@@ -2616,7 +2666,7 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
|
|
|
2616
2666
|
return availableTriggers({
|
|
2617
2667
|
hasMentionableThings: !!(this.boardProvider || this.currentBoard || this.knownTypes?.length),
|
|
2618
2668
|
hasSession: !!this.sessionId,
|
|
2619
|
-
slashTemplateCount:
|
|
2669
|
+
slashTemplateCount: this.conversation.slashTemplates.length
|
|
2620
2670
|
});
|
|
2621
2671
|
}
|
|
2622
2672
|
static { this.EXAMPLE_GROUPS = [
|
|
@@ -2729,8 +2779,8 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
|
|
|
2729
2779
|
<span class="badge">${i18next.t('ai-assistant.label.korean-supported')}</span>
|
|
2730
2780
|
<span class="badge">${i18next.t('ai-assistant.label.multi-command')}</span>
|
|
2731
2781
|
<span class="badge">${i18next.t('ai-assistant.label.review-able')}</span>
|
|
2732
|
-
${
|
|
2733
|
-
? html `<br />${i18next.t(
|
|
2782
|
+
${this.conversation.footerNoticeKey
|
|
2783
|
+
? html `<br />${i18next.t(this.conversation.footerNoticeKey)}`
|
|
2734
2784
|
: ''}
|
|
2735
2785
|
</div>
|
|
2736
2786
|
</div>
|
|
@@ -2872,7 +2922,7 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
|
|
|
2872
2922
|
to live here named a 3D modeller's operations in hardcoded Korean, and it reached the
|
|
2873
2923
|
plant and twin chats too.
|
|
2874
2924
|
*/
|
|
2875
|
-
const rawChoices = Array.isArray(p.choices) ? p.choices :
|
|
2925
|
+
const rawChoices = Array.isArray(p.choices) ? p.choices : this.conversation.proposalChoices;
|
|
2876
2926
|
return html `
|
|
2877
2927
|
<div class="proposal ${sent ? 'sent' : ''}">
|
|
2878
2928
|
<md-icon>${p.icon || (p.source ? 'view_in_ar' : 'bolt')}</md-icon>
|
|
@@ -2900,10 +2950,10 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
|
|
|
2900
2950
|
This badge used to read "there are chips" as "the model is in the 3D viewer" and
|
|
2901
2951
|
say so, in a component that plant and twin also use.
|
|
2902
2952
|
*/''}
|
|
2903
|
-
${this.stagedProposals.has(key) &&
|
|
2953
|
+
${this.stagedProposals.has(key) && this.conversation.stagedNoticeKey ? html `
|
|
2904
2954
|
<span class="staged-badge">
|
|
2905
2955
|
<md-icon>check_circle</md-icon>
|
|
2906
|
-
<span>${i18next.t(
|
|
2956
|
+
<span>${i18next.t(this.conversation.stagedNoticeKey)}</span>
|
|
2907
2957
|
</span>
|
|
2908
2958
|
` : nothing}
|
|
2909
2959
|
</div>
|
|
@@ -3274,7 +3324,7 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
|
|
|
3274
3324
|
let requestBase;
|
|
3275
3325
|
try {
|
|
3276
3326
|
const provided = this.contextProvider?.() || {};
|
|
3277
|
-
requestContext = structuredClone({ systemPrompt: this.systemPrompt, hostContext: this.hostContext, ...provided });
|
|
3327
|
+
requestContext = structuredClone({ systemPrompt: this.conversation.systemPrompt, hostContext: this.conversation.hostContext, ...provided });
|
|
3278
3328
|
liveBoard = structuredClone(this.boardProvider ? this.boardProvider() : this.currentBoard);
|
|
3279
3329
|
requestBase = { version: 1, sessionId: this.sessionId, hostContext: requestContext.hostContext,
|
|
3280
3330
|
modelFingerprint: assistantModelFingerprint(liveBoard) };
|
|
@@ -3348,7 +3398,7 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
|
|
|
3348
3398
|
// 라이브 보드 우선 — 호스트의 캔버스가 사용자 수작업 편집을 들고 있을 수 있음.
|
|
3349
3399
|
// boardProvider 가 있으면 send 시점에 그것을 pull, 없으면 정적 currentBoard.
|
|
3350
3400
|
// mentions 는 위에서 이미 계산해 user line 에 thread — 그대로 mutation 입력으로 재사용.
|
|
3351
|
-
const neutral = this.chatEndpoint === 'assistantChat';
|
|
3401
|
+
const neutral = this.conversation.chatEndpoint === 'assistantChat';
|
|
3352
3402
|
const result = await client.mutate({
|
|
3353
3403
|
mutation: neutral ? ASSISTANT_CHAT_MUTATION : BOARD_AI_CHAT_MUTATION,
|
|
3354
3404
|
variables: {
|
|
@@ -3359,7 +3409,7 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
|
|
|
3359
3409
|
systemPrompt: requestContext.systemPrompt,
|
|
3360
3410
|
truncateAfterMessageId: this._truncateAfterId,
|
|
3361
3411
|
hostContext: requestContext.hostContext,
|
|
3362
|
-
toolCategories: this.toolCategories,
|
|
3412
|
+
toolCategories: this.conversation.toolCategories,
|
|
3363
3413
|
requireGroundingTools: this.requireGroundingTools
|
|
3364
3414
|
})
|
|
3365
3415
|
: buildChatMutationInput({
|
|
@@ -3369,7 +3419,7 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
|
|
|
3369
3419
|
scopes: this.scopes,
|
|
3370
3420
|
truncateAfterMessageId: this._truncateAfterId,
|
|
3371
3421
|
hostContext: requestContext.hostContext,
|
|
3372
|
-
toolCategories: this.toolCategories,
|
|
3422
|
+
toolCategories: this.conversation.toolCategories,
|
|
3373
3423
|
boardTools: this.boardTools,
|
|
3374
3424
|
requireGroundingTools: this.requireGroundingTools,
|
|
3375
3425
|
knownTypes: this.knownTypes,
|
|
@@ -3416,7 +3466,7 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
|
|
|
3416
3466
|
}
|
|
3417
3467
|
// 호스트로 patch 이벤트 전파
|
|
3418
3468
|
if (out.patch) {
|
|
3419
|
-
this.dispatchEvent(new CustomEvent('
|
|
3469
|
+
this.dispatchEvent(new CustomEvent('scene-edit-patch', {
|
|
3420
3470
|
detail: {
|
|
3421
3471
|
patch: out.patch,
|
|
3422
3472
|
requestBase,
|
|
@@ -3431,7 +3481,7 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
|
|
|
3431
3481
|
}
|
|
3432
3482
|
// 호스트로 ephemeral scene 조작 actions 전파 (selection / view / mode)
|
|
3433
3483
|
if (Array.isArray(out.actions) && out.actions.length > 0) {
|
|
3434
|
-
this.dispatchEvent(new CustomEvent('
|
|
3484
|
+
this.dispatchEvent(new CustomEvent('scene-action-execute', {
|
|
3435
3485
|
detail: { actions: out.actions, sessionId: out.sessionId, requestBase },
|
|
3436
3486
|
bubbles: true,
|
|
3437
3487
|
composed: true
|
|
@@ -3504,6 +3554,10 @@ __decorate([
|
|
|
3504
3554
|
property({ type: String, attribute: 'chat-endpoint' }),
|
|
3505
3555
|
__metadata("design:type", String)
|
|
3506
3556
|
], OxAssistantChat.prototype, "chatEndpoint", void 0);
|
|
3557
|
+
__decorate([
|
|
3558
|
+
property({ attribute: false }),
|
|
3559
|
+
__metadata("design:type", Object)
|
|
3560
|
+
], OxAssistantChat.prototype, "mode", void 0);
|
|
3507
3561
|
__decorate([
|
|
3508
3562
|
property({ type: String, attribute: 'system-prompt' }),
|
|
3509
3563
|
__metadata("design:type", String)
|