@things-factory/ai-assistant 10.1.39 → 10.1.42
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 +30 -1
- package/client/utils/assistant-request-context.ts +32 -0
- package/dist-client/components/assistant-chat.d.ts +12 -0
- package/dist-client/components/assistant-chat.js +24 -1
- package/dist-client/components/assistant-chat.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/utils/assistant-request-context.d.ts +23 -0
- package/dist-client/utils/assistant-request-context.js +25 -0
- package/dist-client/utils/assistant-request-context.js.map +1 -1
- package/dist-server/service/assistant-capability-resolver.js +1 -1
- package/dist-server/service/assistant-capability-resolver.js.map +1 -1
- package/dist-server/service/assistant-chat-resolver.js +1 -1
- package/dist-server/service/assistant-chat-resolver.js.map +1 -1
- package/dist-server/service/assistant-mode/assistant-mode-resolver.js +2 -2
- package/dist-server/service/assistant-mode/assistant-mode-resolver.js.map +1 -1
- package/dist-server/service/chat-session/chat-session.js +1 -1
- package/dist-server/service/chat-session/chat-session.js.map +1 -1
- package/dist-server/service/chat-session/session-anchor.d.ts +5 -1
- package/dist-server/service/chat-session/session-anchor.js +23 -1
- package/dist-server/service/chat-session/session-anchor.js.map +1 -1
- package/dist-server/service/chat-session-resolver.js +21 -21
- package/dist-server/service/chat-session-resolver.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/server/service/assistant-capability-resolver.ts +1 -1
- package/server/service/assistant-chat-resolver.ts +1 -1
- package/server/service/assistant-mode/assistant-mode-resolver.ts +2 -2
- package/server/service/chat-session/chat-session.ts +1 -1
- package/server/service/chat-session/session-anchor.ts +26 -1
- package/server/service/chat-session/session-visibility.test.ts +47 -0
- package/server/service/chat-session-resolver.ts +21 -21
- package/server/service/session-anchor.test.ts +55 -1
- package/test/assistant-request-context.test.ts +41 -1
- package/test/open-doors.test.ts +16 -0
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import '@material/web/icon/icon.js'
|
|
17
17
|
import './assistant-session-toolbar.js'
|
|
18
|
-
import { assistantAutoAskKey, assistantModelFingerprint, type AssistantRequestContext } from '../utils/assistant-request-context.js'
|
|
18
|
+
import { assistantAutoAskKey, assistantDraftDecision, assistantModelFingerprint, type AssistantRequestContext } from '../utils/assistant-request-context.js'
|
|
19
19
|
|
|
20
20
|
import { LitElement, css, html, nothing } from 'lit'
|
|
21
21
|
import { customElement, property, state } from 'lit/decorators.js'
|
|
@@ -516,6 +516,18 @@ export class OxAssistantChat extends LitElement {
|
|
|
516
516
|
@property({ attribute: false })
|
|
517
517
|
autoAsk?: string
|
|
518
518
|
@property() autoAskRequestId?: string
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* A sentence to place in the input **without sending it** — the pair of `autoAsk`.
|
|
522
|
+
*
|
|
523
|
+
* Some paths hand the person a starting sentence to edit and send themselves (twin's "new twin →
|
|
524
|
+
* AI"). Filled once per `draftRequestId`, with focus on the input; never over text the person is
|
|
525
|
+
* typing; and when `autoAsk` arrives for the same request, `autoAsk` wins
|
|
526
|
+
* (`assistantDraftDecision`).
|
|
527
|
+
*/
|
|
528
|
+
@property({ attribute: false })
|
|
529
|
+
draft?: string
|
|
530
|
+
@property() draftRequestId?: string
|
|
519
531
|
@property({ attribute: false }) contextProvider?: () => AssistantRequestContext
|
|
520
532
|
|
|
521
533
|
/**
|
|
@@ -548,6 +560,8 @@ export class OxAssistantChat extends LitElement {
|
|
|
548
560
|
|
|
549
561
|
/** autoAsk 를 이미 보냈는지 — 재렌더마다 다시 보내지 않기 위한 표식. */
|
|
550
562
|
private _autoAsked?: string
|
|
563
|
+
/** The draft already placed (or deliberately skipped) — so a re-render does not place it again. */
|
|
564
|
+
private _drafted?: string
|
|
551
565
|
|
|
552
566
|
/** 마지막 send 실패 시 보존 — 다시 시도 버튼 클릭 시 사용 */
|
|
553
567
|
@state()
|
|
@@ -2599,6 +2613,21 @@ export class OxAssistantChat extends LitElement {
|
|
|
2599
2613
|
this.send()
|
|
2600
2614
|
}
|
|
2601
2615
|
|
|
2616
|
+
/* A draft fills the input and waits for the person — it is never sent from here. */
|
|
2617
|
+
const draft = assistantDraftDecision({
|
|
2618
|
+
draft: this.draft,
|
|
2619
|
+
draftRequestId: this.draftRequestId,
|
|
2620
|
+
drafted: this._drafted,
|
|
2621
|
+
typed: this.input,
|
|
2622
|
+
autoAsk: this.autoAsk,
|
|
2623
|
+
autoAskRequestId: this.autoAskRequestId
|
|
2624
|
+
})
|
|
2625
|
+
if (draft.consumed) this._drafted = draft.consumed
|
|
2626
|
+
if (draft.fill) {
|
|
2627
|
+
this.input = this.draft!
|
|
2628
|
+
this.updateComplete.then(() => (this.renderRoot.querySelector('textarea') as HTMLTextAreaElement | null)?.focus())
|
|
2629
|
+
}
|
|
2630
|
+
|
|
2602
2631
|
/*
|
|
2603
2632
|
* The subject changed, so the conversation is over.
|
|
2604
2633
|
*
|
|
@@ -12,6 +12,38 @@ export interface AssistantRequestContext {
|
|
|
12
12
|
export function assistantAutoAskKey(text: string, requestId?: string): string {
|
|
13
13
|
return requestId ? JSON.stringify([requestId, text]) : text
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Whether a draft handed in from outside fills the input now — the pair of `autoAsk` that does not send.
|
|
17
|
+
*
|
|
18
|
+
* A host sometimes wants a sentence placed in the input for the person to edit and send themselves
|
|
19
|
+
* ("new twin → AI" in twin's instance list). Four rules, each a thing a person would notice:
|
|
20
|
+
* · once per request — a re-render must not fill it again after the person cleared or changed it
|
|
21
|
+
* · never over what the person is typing — their text is theirs
|
|
22
|
+
* · when `autoAsk` comes for the same request, it wins — sending is the clearer intent
|
|
23
|
+
* · no draft, nothing to do
|
|
24
|
+
* Returns the key to remember when the draft was consumed (filled, or deliberately skipped), so a
|
|
25
|
+
* skipped draft does not surface later by surprise.
|
|
26
|
+
*/
|
|
27
|
+
export function assistantDraftDecision(input: {
|
|
28
|
+
draft?: string
|
|
29
|
+
draftRequestId?: string
|
|
30
|
+
drafted?: string
|
|
31
|
+
typed: string
|
|
32
|
+
autoAsk?: string
|
|
33
|
+
autoAskRequestId?: string
|
|
34
|
+
}): { fill: boolean; consumed?: string } {
|
|
35
|
+
if (!input.draft) return { fill: false }
|
|
36
|
+
|
|
37
|
+
const key = assistantAutoAskKey(input.draft, input.draftRequestId)
|
|
38
|
+
if (key === input.drafted) return { fill: false }
|
|
39
|
+
|
|
40
|
+
const sameRequestAsked = !!input.autoAsk && !!input.draftRequestId && input.autoAskRequestId === input.draftRequestId
|
|
41
|
+
if (sameRequestAsked) return { fill: false, consumed: key }
|
|
42
|
+
|
|
43
|
+
if (input.typed.trim()) return { fill: false, consumed: key }
|
|
44
|
+
|
|
45
|
+
return { fill: true, consumed: key }
|
|
46
|
+
}
|
|
15
47
|
export function assistantRecentSessions<T extends { id: string }>(sessions: T[], selected: string, limit: number): T[] {
|
|
16
48
|
const count = Math.max(1, Math.floor(limit) || 5)
|
|
17
49
|
const recent = sessions.slice(0, count)
|
|
@@ -171,6 +171,16 @@ export declare class OxAssistantChat extends LitElement {
|
|
|
171
171
|
*/
|
|
172
172
|
autoAsk?: string;
|
|
173
173
|
autoAskRequestId?: string;
|
|
174
|
+
/**
|
|
175
|
+
* A sentence to place in the input **without sending it** — the pair of `autoAsk`.
|
|
176
|
+
*
|
|
177
|
+
* Some paths hand the person a starting sentence to edit and send themselves (twin's "new twin →
|
|
178
|
+
* AI"). Filled once per `draftRequestId`, with focus on the input; never over text the person is
|
|
179
|
+
* typing; and when `autoAsk` arrives for the same request, `autoAsk` wins
|
|
180
|
+
* (`assistantDraftDecision`).
|
|
181
|
+
*/
|
|
182
|
+
draft?: string;
|
|
183
|
+
draftRequestId?: string;
|
|
174
184
|
contextProvider?: () => AssistantRequestContext;
|
|
175
185
|
/**
|
|
176
186
|
* 빈 화면의 제목·부제 — **호스트가 자기 말로 준다.**
|
|
@@ -206,6 +216,8 @@ export declare class OxAssistantChat extends LitElement {
|
|
|
206
216
|
}>;
|
|
207
217
|
/** autoAsk 를 이미 보냈는지 — 재렌더마다 다시 보내지 않기 위한 표식. */
|
|
208
218
|
private _autoAsked?;
|
|
219
|
+
/** The draft already placed (or deliberately skipped) — so a re-render does not place it again. */
|
|
220
|
+
private _drafted?;
|
|
209
221
|
/** 마지막 send 실패 시 보존 — 다시 시도 버튼 클릭 시 사용 */
|
|
210
222
|
private lastFailedInput?;
|
|
211
223
|
/** 되돌려진 patch id 들 — 한 번 revert 한 patch 는 버튼 비활성 */
|
|
@@ -17,7 +17,7 @@ import { __decorate, __metadata } from "tslib";
|
|
|
17
17
|
*/
|
|
18
18
|
import '@material/web/icon/icon.js';
|
|
19
19
|
import './assistant-session-toolbar.js';
|
|
20
|
-
import { assistantAutoAskKey, assistantModelFingerprint } from '../utils/assistant-request-context.js';
|
|
20
|
+
import { assistantAutoAskKey, assistantDraftDecision, assistantModelFingerprint } from '../utils/assistant-request-context.js';
|
|
21
21
|
import { LitElement, css, html, nothing } from 'lit';
|
|
22
22
|
import { customElement, property, state } from 'lit/decorators.js';
|
|
23
23
|
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
|
@@ -2272,6 +2272,21 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
|
|
|
2272
2272
|
this.input = this.autoAsk;
|
|
2273
2273
|
this.send();
|
|
2274
2274
|
}
|
|
2275
|
+
/* A draft fills the input and waits for the person — it is never sent from here. */
|
|
2276
|
+
const draft = assistantDraftDecision({
|
|
2277
|
+
draft: this.draft,
|
|
2278
|
+
draftRequestId: this.draftRequestId,
|
|
2279
|
+
drafted: this._drafted,
|
|
2280
|
+
typed: this.input,
|
|
2281
|
+
autoAsk: this.autoAsk,
|
|
2282
|
+
autoAskRequestId: this.autoAskRequestId
|
|
2283
|
+
});
|
|
2284
|
+
if (draft.consumed)
|
|
2285
|
+
this._drafted = draft.consumed;
|
|
2286
|
+
if (draft.fill) {
|
|
2287
|
+
this.input = this.draft;
|
|
2288
|
+
this.updateComplete.then(() => this.renderRoot.querySelector('textarea')?.focus());
|
|
2289
|
+
}
|
|
2275
2290
|
/*
|
|
2276
2291
|
* The subject changed, so the conversation is over.
|
|
2277
2292
|
*
|
|
@@ -4199,6 +4214,14 @@ __decorate([
|
|
|
4199
4214
|
property(),
|
|
4200
4215
|
__metadata("design:type", String)
|
|
4201
4216
|
], OxAssistantChat.prototype, "autoAskRequestId", void 0);
|
|
4217
|
+
__decorate([
|
|
4218
|
+
property({ attribute: false }),
|
|
4219
|
+
__metadata("design:type", String)
|
|
4220
|
+
], OxAssistantChat.prototype, "draft", void 0);
|
|
4221
|
+
__decorate([
|
|
4222
|
+
property(),
|
|
4223
|
+
__metadata("design:type", String)
|
|
4224
|
+
], OxAssistantChat.prototype, "draftRequestId", void 0);
|
|
4202
4225
|
__decorate([
|
|
4203
4226
|
property({ attribute: false }),
|
|
4204
4227
|
__metadata("design:type", Function)
|