feat(core): provide document title, tags, createTime and updateTime to llm (#11205)

Close [BS-2915](https://linear.app/affine-design/issue/BS-2915).
This commit is contained in:
akumatus
2025-03-27 04:34:45 +00:00
parent 0c73fde44a
commit 22ef32f5c2
6 changed files with 54 additions and 4 deletions

View File

@@ -6,7 +6,7 @@ import type {
} from '@affine/core/modules/search-menu/services';
import type { Collection } from '@affine/env/filter';
import type { LinkedMenuGroup } from '@blocksuite/affine/blocks/root';
import type { Store } from '@blocksuite/affine/store';
import type { DocMeta, Store } from '@blocksuite/affine/store';
import type { Signal } from '@preact/signals-core';
export interface AppSidebarConfig {
@@ -33,6 +33,7 @@ export interface DocDisplayConfig {
signal: Signal<string>;
cleanup: () => void;
};
getDocMeta: (docId: string) => Partial<DocMeta> | null;
getDoc: (docId: string) => Store | null;
getReferenceDocs: (docIds: string[]) => {
signal: Signal<
@@ -47,6 +48,7 @@ export interface DocDisplayConfig {
signal: Signal<TagMeta[]>;
cleanup: () => void;
};
getTagTitle: (tagId: string) => string;
getTagPageIds: (tagId: string) => string[];
getCollections: () => {
signal: Signal<Collection[]>;

View File

@@ -36,7 +36,11 @@ export type ChatStatus =
export interface DocContext {
docId: string;
docTitle: string;
docContent: string;
tags: string;
createDate: string;
updatedDate: string;
}
export interface FileContext {

View File

@@ -18,7 +18,7 @@ import type { AIError } from '../components/ai-item/types';
import { AIProvider } from '../provider';
import { reportResponse } from '../utils/action-reporter';
import { readBlobAsURL } from '../utils/image';
import type { AINetworkSearchConfig } from './chat-config';
import type { AINetworkSearchConfig, DocDisplayConfig } from './chat-config';
import type {
ChatContextValue,
ChatMessage,
@@ -217,6 +217,9 @@ export class ChatPanelInput extends SignalWatcher(WithDisposable(LitElement)) {
@property({ attribute: false })
accessor networkSearchConfig!: AINetworkSearchConfig;
@property({ attribute: false })
accessor docDisplayConfig!: DocDisplayConfig;
private get _isNetworkActive() {
return (
!!this.networkSearchConfig.visible.value &&
@@ -561,7 +564,10 @@ export class ChatPanelInput extends SignalWatcher(WithDisposable(LitElement)) {
return { files: [], docs: [] };
}
const docContexts = new Map<string, DocContext>();
const docContexts = new Map<
string,
{ docId: string; docContent: string }
>();
const fileContexts = new Map<string, FileContext>();
const { files: matchedFiles = [], docs: matchedDocs = [] } =
@@ -602,8 +608,30 @@ export class ChatPanelInput extends SignalWatcher(WithDisposable(LitElement)) {
}
});
const docs: DocContext[] = Array.from(docContexts.values()).map(doc => {
const docMeta = this.docDisplayConfig.getDocMeta(doc.docId);
const docTitle = this.docDisplayConfig.getTitle(doc.docId);
const tags = docMeta?.tags
? docMeta.tags
.map(tagId => this.docDisplayConfig.getTagTitle(tagId))
.join(',')
: '';
return {
docId: doc.docId,
docContent: doc.docContent,
docTitle,
tags,
createDate: docMeta?.createDate
? new Date(docMeta.createDate).toISOString()
: '',
updatedDate: docMeta?.updatedDate
? new Date(docMeta.updatedDate).toISOString()
: '',
};
});
return {
docs: Array.from(docContexts.values()),
docs,
files: Array.from(fileContexts.values()),
};
}

View File

@@ -629,6 +629,7 @@ export class ChatPanel extends SignalWatcher(
.getSessionId=${this._getSessionId}
.getContextId=${this._getContextId}
.networkSearchConfig=${this.networkSearchConfig}
.docDisplayConfig=${this.docDisplayConfig}
.updateContext=${this.updateContext}
.host=${this.host}
.cleanupHistories=${this._cleanupHistories}

View File

@@ -3,6 +3,7 @@ import type { AffineEditorContainer } from '@affine/core/blocksuite/block-suite-
import { enableFootnoteConfigExtension } from '@affine/core/blocksuite/extensions';
import { AINetworkSearchService } from '@affine/core/modules/ai-button/services/network-search';
import { CollectionService } from '@affine/core/modules/collection';
import { DocsService } from '@affine/core/modules/doc';
import { DocDisplayMetaService } from '@affine/core/modules/doc-display-meta';
import { DocsSearchService } from '@affine/core/modules/docs-search';
import { SearchMenuService } from '@affine/core/modules/search-menu/services';
@@ -66,6 +67,8 @@ export const EditorChatPanel = forwardRef(function EditorChatPanel(
const docsSearchService = framework.get(DocsSearchService);
const tagService = framework.get(TagService);
const collectionService = framework.get(CollectionService);
const docsService = framework.get(DocsService);
chatPanelRef.current.appSidebarConfig = {
getWidth: () => {
const width$ = workbench.sidebarWidth$;
@@ -94,6 +97,10 @@ export const EditorChatPanel = forwardRef(function EditorChatPanel(
const title$ = docDisplayMetaService.title$(docId);
return createSignalFromObservable(title$, '');
},
getDocMeta: (docId: string) => {
const docRecord = docsService.list.doc$(docId).value;
return docRecord?.meta$.value ?? null;
},
getDoc: (docId: string) => {
const doc = workspaceService.workspace.docCollection.getDoc(docId);
return doc?.getStore() ?? null;
@@ -106,6 +113,10 @@ export const EditorChatPanel = forwardRef(function EditorChatPanel(
const tagMetas$ = tagService.tagList.tagMetas$;
return createSignalFromObservable(tagMetas$, []);
},
getTagTitle: (tagId: string) => {
const tag$ = tagService.tagList.tagByTagId$(tagId);
return tag$.value?.value$.value ?? '';
},
getTagPageIds: (tagId: string) => {
const tag$ = tagService.tagList.tagByTagId$(tagId);
if (!tag$) return [];