mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-11 22:18:54 +08:00
feat(server): improve context metadata & matching (#12064)
fix AI-20 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Enhanced file metadata with MIME type, blob ID, and file name across context and workspace, now visible in UI and API. - Added workspace-level matching for files and documents with configurable thresholds and workspace scoping in search queries. - Introduced a new error type and user-friendly messaging for global workspace context matching failures. - **Bug Fixes** - Improved consistent handling of file MIME types and nullable context IDs for accurate metadata. - **Documentation** - Updated GraphQL schema, queries, and mutations to include new metadata fields, optional parameters, and error types. - **Style** - Added new localization strings for global context matching error messages. - **Tests** - Extended test coverage with new and updated snapshot tests for metadata and matching logic. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -329,9 +329,12 @@ declare global {
|
||||
abortSignal: AbortSignal
|
||||
) => Promise<void>;
|
||||
matchContext: (
|
||||
contextId: string,
|
||||
content: string,
|
||||
limit?: number
|
||||
contextId?: string,
|
||||
workspaceId?: string,
|
||||
limit?: number,
|
||||
scopedThreshold?: number,
|
||||
threshold?: number
|
||||
) => Promise<{
|
||||
files?: ContextMatchedFileChunk[];
|
||||
docs?: ContextMatchedDocChunk[];
|
||||
|
||||
@@ -661,7 +661,7 @@ export class AIChatInput extends SignalWatcher(WithDisposable(LitElement)) {
|
||||
>();
|
||||
|
||||
const { files: matchedFiles = [], docs: matchedDocs = [] } =
|
||||
(await AIProvider.context?.matchContext(contextId, userInput)) ?? {};
|
||||
(await AIProvider.context?.matchContext(userInput, contextId)) ?? {};
|
||||
|
||||
matchedDocs.forEach(doc => {
|
||||
docContexts.set(doc.docId, {
|
||||
|
||||
@@ -241,7 +241,7 @@ export class CopilotClient {
|
||||
sessionId,
|
||||
},
|
||||
});
|
||||
return res.currentUser?.copilot?.contexts?.[0]?.id;
|
||||
return res.currentUser?.copilot?.contexts?.[0]?.id || undefined;
|
||||
}
|
||||
|
||||
async addContextDoc(options: OptionsField<typeof addContextDocMutation>) {
|
||||
@@ -333,13 +333,23 @@ export class CopilotClient {
|
||||
return res.currentUser?.copilot?.contexts?.[0];
|
||||
}
|
||||
|
||||
async matchContext(contextId: string, content: string, limit?: number) {
|
||||
async matchContext(
|
||||
content: string,
|
||||
contextId?: string,
|
||||
workspaceId?: string,
|
||||
limit?: number,
|
||||
scopedThreshold?: number,
|
||||
threshold?: number
|
||||
) {
|
||||
const res = await this.gql({
|
||||
query: matchContextQuery,
|
||||
variables: {
|
||||
contextId,
|
||||
content,
|
||||
contextId,
|
||||
workspaceId,
|
||||
limit,
|
||||
scopedThreshold,
|
||||
threshold,
|
||||
},
|
||||
});
|
||||
const { matchFiles: files, matchWorkspaceDocs: docs } =
|
||||
|
||||
@@ -700,11 +700,21 @@ Could you make a new website based on these notes and send back just the html fi
|
||||
}
|
||||
},
|
||||
matchContext: async (
|
||||
contextId: string,
|
||||
content: string,
|
||||
limit?: number
|
||||
contextId?: string,
|
||||
workspaceId?: string,
|
||||
limit?: number,
|
||||
scopedThreshold?: number,
|
||||
threshold?: number
|
||||
) => {
|
||||
return client.matchContext(contextId, content, limit);
|
||||
return client.matchContext(
|
||||
content,
|
||||
contextId,
|
||||
workspaceId,
|
||||
limit,
|
||||
scopedThreshold,
|
||||
threshold
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user