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:
@@ -1045,6 +1045,10 @@ The following content is a relevant content segment:
|
|||||||
==========
|
==========
|
||||||
- type: document
|
- type: document
|
||||||
- document_id: {{docId}}
|
- document_id: {{docId}}
|
||||||
|
- document_title: {{docTitle}}
|
||||||
|
- document_tags: {{tags}}
|
||||||
|
- document_create_date: {{createDate}}
|
||||||
|
- document_updated_date: {{updatedDate}}
|
||||||
- document_content:
|
- document_content:
|
||||||
{{docContent}}
|
{{docContent}}
|
||||||
==========
|
==========
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import type {
|
|||||||
} from '@affine/core/modules/search-menu/services';
|
} from '@affine/core/modules/search-menu/services';
|
||||||
import type { Collection } from '@affine/env/filter';
|
import type { Collection } from '@affine/env/filter';
|
||||||
import type { LinkedMenuGroup } from '@blocksuite/affine/blocks/root';
|
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';
|
import type { Signal } from '@preact/signals-core';
|
||||||
|
|
||||||
export interface AppSidebarConfig {
|
export interface AppSidebarConfig {
|
||||||
@@ -33,6 +33,7 @@ export interface DocDisplayConfig {
|
|||||||
signal: Signal<string>;
|
signal: Signal<string>;
|
||||||
cleanup: () => void;
|
cleanup: () => void;
|
||||||
};
|
};
|
||||||
|
getDocMeta: (docId: string) => Partial<DocMeta> | null;
|
||||||
getDoc: (docId: string) => Store | null;
|
getDoc: (docId: string) => Store | null;
|
||||||
getReferenceDocs: (docIds: string[]) => {
|
getReferenceDocs: (docIds: string[]) => {
|
||||||
signal: Signal<
|
signal: Signal<
|
||||||
@@ -47,6 +48,7 @@ export interface DocDisplayConfig {
|
|||||||
signal: Signal<TagMeta[]>;
|
signal: Signal<TagMeta[]>;
|
||||||
cleanup: () => void;
|
cleanup: () => void;
|
||||||
};
|
};
|
||||||
|
getTagTitle: (tagId: string) => string;
|
||||||
getTagPageIds: (tagId: string) => string[];
|
getTagPageIds: (tagId: string) => string[];
|
||||||
getCollections: () => {
|
getCollections: () => {
|
||||||
signal: Signal<Collection[]>;
|
signal: Signal<Collection[]>;
|
||||||
|
|||||||
@@ -36,7 +36,11 @@ export type ChatStatus =
|
|||||||
|
|
||||||
export interface DocContext {
|
export interface DocContext {
|
||||||
docId: string;
|
docId: string;
|
||||||
|
docTitle: string;
|
||||||
docContent: string;
|
docContent: string;
|
||||||
|
tags: string;
|
||||||
|
createDate: string;
|
||||||
|
updatedDate: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FileContext {
|
export interface FileContext {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import type { AIError } from '../components/ai-item/types';
|
|||||||
import { AIProvider } from '../provider';
|
import { AIProvider } from '../provider';
|
||||||
import { reportResponse } from '../utils/action-reporter';
|
import { reportResponse } from '../utils/action-reporter';
|
||||||
import { readBlobAsURL } from '../utils/image';
|
import { readBlobAsURL } from '../utils/image';
|
||||||
import type { AINetworkSearchConfig } from './chat-config';
|
import type { AINetworkSearchConfig, DocDisplayConfig } from './chat-config';
|
||||||
import type {
|
import type {
|
||||||
ChatContextValue,
|
ChatContextValue,
|
||||||
ChatMessage,
|
ChatMessage,
|
||||||
@@ -217,6 +217,9 @@ export class ChatPanelInput extends SignalWatcher(WithDisposable(LitElement)) {
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor networkSearchConfig!: AINetworkSearchConfig;
|
accessor networkSearchConfig!: AINetworkSearchConfig;
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
accessor docDisplayConfig!: DocDisplayConfig;
|
||||||
|
|
||||||
private get _isNetworkActive() {
|
private get _isNetworkActive() {
|
||||||
return (
|
return (
|
||||||
!!this.networkSearchConfig.visible.value &&
|
!!this.networkSearchConfig.visible.value &&
|
||||||
@@ -561,7 +564,10 @@ export class ChatPanelInput extends SignalWatcher(WithDisposable(LitElement)) {
|
|||||||
return { files: [], docs: [] };
|
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 fileContexts = new Map<string, FileContext>();
|
||||||
|
|
||||||
const { files: matchedFiles = [], docs: matchedDocs = [] } =
|
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 {
|
return {
|
||||||
docs: Array.from(docContexts.values()),
|
docs,
|
||||||
files: Array.from(fileContexts.values()),
|
files: Array.from(fileContexts.values()),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -629,6 +629,7 @@ export class ChatPanel extends SignalWatcher(
|
|||||||
.getSessionId=${this._getSessionId}
|
.getSessionId=${this._getSessionId}
|
||||||
.getContextId=${this._getContextId}
|
.getContextId=${this._getContextId}
|
||||||
.networkSearchConfig=${this.networkSearchConfig}
|
.networkSearchConfig=${this.networkSearchConfig}
|
||||||
|
.docDisplayConfig=${this.docDisplayConfig}
|
||||||
.updateContext=${this.updateContext}
|
.updateContext=${this.updateContext}
|
||||||
.host=${this.host}
|
.host=${this.host}
|
||||||
.cleanupHistories=${this._cleanupHistories}
|
.cleanupHistories=${this._cleanupHistories}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import type { AffineEditorContainer } from '@affine/core/blocksuite/block-suite-
|
|||||||
import { enableFootnoteConfigExtension } from '@affine/core/blocksuite/extensions';
|
import { enableFootnoteConfigExtension } from '@affine/core/blocksuite/extensions';
|
||||||
import { AINetworkSearchService } from '@affine/core/modules/ai-button/services/network-search';
|
import { AINetworkSearchService } from '@affine/core/modules/ai-button/services/network-search';
|
||||||
import { CollectionService } from '@affine/core/modules/collection';
|
import { CollectionService } from '@affine/core/modules/collection';
|
||||||
|
import { DocsService } from '@affine/core/modules/doc';
|
||||||
import { DocDisplayMetaService } from '@affine/core/modules/doc-display-meta';
|
import { DocDisplayMetaService } from '@affine/core/modules/doc-display-meta';
|
||||||
import { DocsSearchService } from '@affine/core/modules/docs-search';
|
import { DocsSearchService } from '@affine/core/modules/docs-search';
|
||||||
import { SearchMenuService } from '@affine/core/modules/search-menu/services';
|
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 docsSearchService = framework.get(DocsSearchService);
|
||||||
const tagService = framework.get(TagService);
|
const tagService = framework.get(TagService);
|
||||||
const collectionService = framework.get(CollectionService);
|
const collectionService = framework.get(CollectionService);
|
||||||
|
const docsService = framework.get(DocsService);
|
||||||
|
|
||||||
chatPanelRef.current.appSidebarConfig = {
|
chatPanelRef.current.appSidebarConfig = {
|
||||||
getWidth: () => {
|
getWidth: () => {
|
||||||
const width$ = workbench.sidebarWidth$;
|
const width$ = workbench.sidebarWidth$;
|
||||||
@@ -94,6 +97,10 @@ export const EditorChatPanel = forwardRef(function EditorChatPanel(
|
|||||||
const title$ = docDisplayMetaService.title$(docId);
|
const title$ = docDisplayMetaService.title$(docId);
|
||||||
return createSignalFromObservable(title$, '');
|
return createSignalFromObservable(title$, '');
|
||||||
},
|
},
|
||||||
|
getDocMeta: (docId: string) => {
|
||||||
|
const docRecord = docsService.list.doc$(docId).value;
|
||||||
|
return docRecord?.meta$.value ?? null;
|
||||||
|
},
|
||||||
getDoc: (docId: string) => {
|
getDoc: (docId: string) => {
|
||||||
const doc = workspaceService.workspace.docCollection.getDoc(docId);
|
const doc = workspaceService.workspace.docCollection.getDoc(docId);
|
||||||
return doc?.getStore() ?? null;
|
return doc?.getStore() ?? null;
|
||||||
@@ -106,6 +113,10 @@ export const EditorChatPanel = forwardRef(function EditorChatPanel(
|
|||||||
const tagMetas$ = tagService.tagList.tagMetas$;
|
const tagMetas$ = tagService.tagList.tagMetas$;
|
||||||
return createSignalFromObservable(tagMetas$, []);
|
return createSignalFromObservable(tagMetas$, []);
|
||||||
},
|
},
|
||||||
|
getTagTitle: (tagId: string) => {
|
||||||
|
const tag$ = tagService.tagList.tagByTagId$(tagId);
|
||||||
|
return tag$.value?.value$.value ?? '';
|
||||||
|
},
|
||||||
getTagPageIds: (tagId: string) => {
|
getTagPageIds: (tagId: string) => {
|
||||||
const tag$ = tagService.tagList.tagByTagId$(tagId);
|
const tag$ = tagService.tagList.tagByTagId$(tagId);
|
||||||
if (!tag$) return [];
|
if (!tag$) return [];
|
||||||
|
|||||||
Reference in New Issue
Block a user