mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-26 02:35:58 +08:00
feat(core): ai intelligence track (#13187)
Close [AI-335](https://linear.app/affine-design/issue/AI-335) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for an "independent mode" and document-specific context in AI chat components, allowing enhanced context handling and tracking. * Introduced new tracking options to distinguish between current document and general document actions in chat interactions. * **Improvements** * More flexible property handling for independent mode and document context across chat-related components for consistent behavior and tracking. * Enhanced tracking system to support additional event categories and methods for more granular analytics. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -80,7 +80,7 @@ export class ChatMessageAssistant extends WithDisposable(ShadowlessElement) {
|
||||
accessor notificationService!: NotificationService;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor independentMode!: boolean;
|
||||
accessor independentMode: boolean | undefined;
|
||||
|
||||
get state() {
|
||||
const { isLast, status } = this;
|
||||
|
||||
@@ -23,6 +23,12 @@ export class AIChatAddContext extends SignalWatcher(
|
||||
}
|
||||
`;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor docId: string | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor independentMode: boolean | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor addChip!: (chip: ChatChip) => Promise<void>;
|
||||
|
||||
@@ -69,6 +75,8 @@ export class AIChatAddContext extends SignalWatcher(
|
||||
createLitPortal({
|
||||
template: html`
|
||||
<chat-panel-add-popover
|
||||
.docId=${this.docId}
|
||||
.independentMode=${this.independentMode}
|
||||
.addChip=${this.addChip}
|
||||
.addImages=${this.addImages}
|
||||
.searchMenuConfig=${this.searchMenuConfig}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { toast } from '@affine/component';
|
||||
import type { TagMeta } from '@affine/core/components/page-list';
|
||||
import type { CollectionMeta } from '@affine/core/modules/collection';
|
||||
import track from '@affine/track';
|
||||
import track, { type EventArgs } from '@affine/track';
|
||||
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import { scrollbarStyle } from '@blocksuite/affine/shared/styles';
|
||||
import { unsafeCSSVar, unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
||||
@@ -120,6 +120,12 @@ export class ChatPanelAddPopover extends SignalWatcher(
|
||||
|
||||
private accessor _query = '';
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor independentMode: boolean | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor docId: string | undefined;
|
||||
|
||||
@state()
|
||||
private accessor _searchGroups: MenuGroup[] = [];
|
||||
|
||||
@@ -497,7 +503,8 @@ export class ChatPanelAddPopover extends SignalWatcher(
|
||||
state: 'processing',
|
||||
});
|
||||
const mode = this.docDisplayConfig.getDocPrimaryMode(meta.id);
|
||||
this._track('doc', mode);
|
||||
const method = meta.id === this.docId ? 'cur-doc' : 'doc';
|
||||
this._track(method, mode);
|
||||
};
|
||||
|
||||
private readonly _addTagChip = async (tag: TagMeta) => {
|
||||
@@ -561,10 +568,13 @@ export class ChatPanelAddPopover extends SignalWatcher(
|
||||
}
|
||||
|
||||
private _track(
|
||||
method: 'doc' | 'file' | 'tags' | 'collections',
|
||||
method: EventArgs['addEmbeddingDoc']['method'],
|
||||
type?: 'page' | 'edgeless'
|
||||
) {
|
||||
track.$.chatPanel.chatPanelInput.addEmbeddingDoc({
|
||||
const page = this.independentMode
|
||||
? track.$.intelligence
|
||||
: track.$.chatPanel;
|
||||
page.chatPanelInput.addEmbeddingDoc({
|
||||
control: 'addButton',
|
||||
method,
|
||||
type,
|
||||
|
||||
@@ -81,6 +81,9 @@ export class ChatPanelChips extends SignalWatcher(
|
||||
@property({ attribute: false })
|
||||
accessor isCollapsed!: boolean;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor independentMode: boolean | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor addChip!: (chip: ChatChip) => Promise<void>;
|
||||
|
||||
@@ -142,6 +145,7 @@ export class ChatPanelChips extends SignalWatcher(
|
||||
if (isDocChip(chip)) {
|
||||
return html`<chat-panel-doc-chip
|
||||
.chip=${chip}
|
||||
.independentMode=${this.independentMode}
|
||||
.addChip=${this.addChip}
|
||||
.updateChip=${this.updateChip}
|
||||
.removeChip=${this.removeChip}
|
||||
|
||||
@@ -18,6 +18,9 @@ export class ChatPanelDocChip extends SignalWatcher(
|
||||
@property({ attribute: false })
|
||||
accessor chip!: DocChip;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor independentMode: boolean | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor addChip!: (chip: DocChip) => void;
|
||||
|
||||
@@ -81,7 +84,10 @@ export class ChatPanelDocChip extends SignalWatcher(
|
||||
state: 'processing',
|
||||
});
|
||||
const mode = this.docDisplayConfig.getDocPrimaryMode(this.chip.docId);
|
||||
track.$.chatPanel.chatPanelInput.addEmbeddingDoc({
|
||||
const page = this.independentMode
|
||||
? track.$.intelligence
|
||||
: track.$.chatPanel;
|
||||
page.chatPanelInput.addEmbeddingDoc({
|
||||
control: 'addButton',
|
||||
method: 'suggestion',
|
||||
type: mode,
|
||||
|
||||
@@ -59,7 +59,7 @@ export class AIChatComposer extends SignalWatcher(
|
||||
`;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor independentMode!: boolean;
|
||||
accessor independentMode: boolean | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor host: EditorHost | null | undefined;
|
||||
@@ -85,9 +85,9 @@ export class AIChatComposer extends SignalWatcher(
|
||||
accessor updateContext!: (context: Partial<AIChatInputContext>) => void;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor onEmbeddingProgressChange!: (
|
||||
count: Record<ContextEmbedStatus, number>
|
||||
) => void;
|
||||
accessor onEmbeddingProgressChange:
|
||||
| ((count: Record<ContextEmbedStatus, number>) => void)
|
||||
| undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor docDisplayConfig!: DocDisplayConfig;
|
||||
@@ -136,6 +136,7 @@ export class AIChatComposer extends SignalWatcher(
|
||||
<chat-panel-chips
|
||||
.chips=${this.chips}
|
||||
.isCollapsed=${this.isChipsCollapsed}
|
||||
.independentMode=${this.independentMode}
|
||||
.addChip=${this.addChip}
|
||||
.updateChip=${this.updateChip}
|
||||
.removeChip=${this.removeChip}
|
||||
@@ -603,7 +604,7 @@ export class AIChatComposer extends SignalWatcher(
|
||||
return chip;
|
||||
});
|
||||
this.updateChips(nextChips);
|
||||
this.onEmbeddingProgressChange(count);
|
||||
this.onEmbeddingProgressChange?.(count);
|
||||
if (count.processing === 0) {
|
||||
this._abortPoll();
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ export class AIChatContent extends SignalWatcher(
|
||||
`;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor independentMode!: boolean;
|
||||
accessor independentMode: boolean | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor onboardingOffsetY!: number;
|
||||
@@ -177,9 +177,9 @@ export class AIChatContent extends SignalWatcher(
|
||||
accessor notificationService!: NotificationService;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor onEmbeddingProgressChange!: (
|
||||
count: Record<ContextEmbedStatus, number>
|
||||
) => void;
|
||||
accessor onEmbeddingProgressChange:
|
||||
| ((count: Record<ContextEmbedStatus, number>) => void)
|
||||
| undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor onContextChange!: (context: Partial<ChatContextValue>) => void;
|
||||
@@ -403,7 +403,7 @@ export class AIChatContent extends SignalWatcher(
|
||||
<ai-chat-messages
|
||||
class=${classMap({
|
||||
'ai-chat-messages': true,
|
||||
'independent-mode': this.independentMode,
|
||||
'independent-mode': !!this.independentMode,
|
||||
'no-message': this.messages.length === 0,
|
||||
})}
|
||||
${ref(this.chatMessagesRef)}
|
||||
|
||||
@@ -290,7 +290,7 @@ export class AIChatInput extends SignalWatcher(
|
||||
`;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor independentMode!: boolean;
|
||||
accessor independentMode: boolean | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor host: EditorHost | null | undefined;
|
||||
@@ -458,6 +458,8 @@ export class AIChatInput extends SignalWatcher(
|
||||
<div class="chat-panel-input-actions">
|
||||
<div class="chat-input-icon">
|
||||
<ai-chat-add-context
|
||||
.docId=${this.docId}
|
||||
.independentMode=${this.independentMode}
|
||||
.addChip=${this.addChip}
|
||||
.addImages=${this.addImages}
|
||||
.docDisplayConfig=${this.docDisplayConfig}
|
||||
|
||||
@@ -150,7 +150,7 @@ export class AIChatMessages extends WithDisposable(ShadowlessElement) {
|
||||
accessor avatarUrl = '';
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor independentMode!: boolean;
|
||||
accessor independentMode: boolean | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor messages!: HistoryMessage[];
|
||||
@@ -275,7 +275,7 @@ export class AIChatMessages extends WithDisposable(ShadowlessElement) {
|
||||
<div
|
||||
class=${classMap({
|
||||
'chat-panel-messages-container': true,
|
||||
'independent-mode': this.independentMode,
|
||||
'independent-mode': !!this.independentMode,
|
||||
})}
|
||||
data-testid="chat-panel-messages-container"
|
||||
@scroll=${() => this._debouncedOnScroll()}
|
||||
|
||||
Reference in New Issue
Block a user