mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-20 19:46:32 +08:00
feat(server): summary tools (#13133)
fix AI-281 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a new AI-powered conversation summary tool that generates concise summaries of key topics, decisions, and details from conversations, with options to focus on specific areas and adjust summary length. * Introduced a new prompt for conversation summarization, supporting customizable focus and summary length. * **Bug Fixes** * Improved tool handling and error messages for conversation summarization when required input is missing. * **Tests** * Expanded test coverage to include scenarios for the new conversation summary feature. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -21,6 +21,7 @@ import {
|
||||
buildDocKeywordSearchGetter,
|
||||
buildDocSearchGetter,
|
||||
createCodeArtifactTool,
|
||||
createConversationSummaryTool,
|
||||
createDocComposeTool,
|
||||
createDocEditTool,
|
||||
createDocKeywordSearchTool,
|
||||
@@ -139,6 +140,10 @@ export abstract class CopilotProvider<C = any> {
|
||||
if (options?.tools?.length) {
|
||||
this.logger.debug(`getTools: ${JSON.stringify(options.tools)}`);
|
||||
const ac = this.moduleRef.get(AccessController, { strict: false });
|
||||
const docReader = this.moduleRef.get(DocReader, { strict: false });
|
||||
const prompt = this.moduleRef.get(PromptService, {
|
||||
strict: false,
|
||||
});
|
||||
|
||||
for (const tool of options.tools) {
|
||||
const toolDef = this.getProviderSpecificTools(tool, model);
|
||||
@@ -150,9 +155,20 @@ export abstract class CopilotProvider<C = any> {
|
||||
continue;
|
||||
}
|
||||
switch (tool) {
|
||||
case 'codeArtifact': {
|
||||
tools.code_artifact = createCodeArtifactTool(prompt, this.factory);
|
||||
break;
|
||||
}
|
||||
case 'conversationSummary': {
|
||||
tools.conversation_summary = createConversationSummaryTool(
|
||||
options.session,
|
||||
prompt,
|
||||
this.factory
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'docEdit': {
|
||||
const doc = this.moduleRef.get(DocReader, { strict: false });
|
||||
const getDocContent = buildContentGetter(ac, doc);
|
||||
const getDocContent = buildContentGetter(ac, docReader);
|
||||
tools.doc_edit = createDocEditTool(
|
||||
this.factory,
|
||||
getDocContent.bind(null, options)
|
||||
@@ -163,7 +179,6 @@ export abstract class CopilotProvider<C = any> {
|
||||
const context = this.moduleRef.get(CopilotContextService, {
|
||||
strict: false,
|
||||
});
|
||||
|
||||
const docContext = options.session
|
||||
? await context.getBySessionId(options.session)
|
||||
: null;
|
||||
@@ -175,9 +190,6 @@ export abstract class CopilotProvider<C = any> {
|
||||
}
|
||||
case 'docKeywordSearch': {
|
||||
if (this.AFFiNEConfig.indexer.enabled) {
|
||||
const ac = this.moduleRef.get(AccessController, {
|
||||
strict: false,
|
||||
});
|
||||
const indexerService = this.moduleRef.get(IndexerService, {
|
||||
strict: false,
|
||||
});
|
||||
@@ -192,9 +204,7 @@ export abstract class CopilotProvider<C = any> {
|
||||
break;
|
||||
}
|
||||
case 'docRead': {
|
||||
const ac = this.moduleRef.get(AccessController, { strict: false });
|
||||
const models = this.moduleRef.get(Models, { strict: false });
|
||||
const docReader = this.moduleRef.get(DocReader, { strict: false });
|
||||
const getDoc = buildDocContentGetter(ac, docReader, models);
|
||||
tools.doc_read = createDocReadTool(getDoc.bind(null, options));
|
||||
break;
|
||||
@@ -205,23 +215,7 @@ export abstract class CopilotProvider<C = any> {
|
||||
break;
|
||||
}
|
||||
case 'docCompose': {
|
||||
const promptService = this.moduleRef.get(PromptService, {
|
||||
strict: false,
|
||||
});
|
||||
tools.doc_compose = createDocComposeTool(
|
||||
promptService,
|
||||
this.factory
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'codeArtifact': {
|
||||
const promptService = this.moduleRef.get(PromptService, {
|
||||
strict: false,
|
||||
});
|
||||
tools.code_artifact = createCodeArtifactTool(
|
||||
promptService,
|
||||
this.factory
|
||||
);
|
||||
tools.doc_compose = createDocComposeTool(prompt, this.factory);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,8 @@ export const VertexSchema: JSONSchema = {
|
||||
export const PromptConfigStrictSchema = z.object({
|
||||
tools: z
|
||||
.enum([
|
||||
'codeArtifact',
|
||||
'conversationSummary',
|
||||
// work with morph
|
||||
'docEdit',
|
||||
// work with indexer
|
||||
@@ -71,7 +73,6 @@ export const PromptConfigStrictSchema = z.object({
|
||||
'webSearch',
|
||||
// artifact tools
|
||||
'docCompose',
|
||||
'codeArtifact',
|
||||
])
|
||||
.array()
|
||||
.nullable()
|
||||
|
||||
@@ -6,20 +6,10 @@ import {
|
||||
ImagePart,
|
||||
TextPart,
|
||||
TextStreamPart,
|
||||
ToolSet,
|
||||
} from 'ai';
|
||||
import { ZodType } from 'zod';
|
||||
|
||||
import {
|
||||
createCodeArtifactTool,
|
||||
createDocComposeTool,
|
||||
createDocEditTool,
|
||||
createDocKeywordSearchTool,
|
||||
createDocReadTool,
|
||||
createDocSemanticSearchTool,
|
||||
createExaCrawlTool,
|
||||
createExaSearchTool,
|
||||
} from '../tools';
|
||||
import { CustomAITools } from '../tools';
|
||||
import { PromptMessage, StreamObject } from './types';
|
||||
|
||||
type ChatMessage = CoreUserMessage | CoreAssistantMessage;
|
||||
@@ -385,17 +375,6 @@ export class CitationParser {
|
||||
}
|
||||
}
|
||||
|
||||
export interface CustomAITools extends ToolSet {
|
||||
doc_edit: ReturnType<typeof createDocEditTool>;
|
||||
doc_semantic_search: ReturnType<typeof createDocSemanticSearchTool>;
|
||||
doc_keyword_search: ReturnType<typeof createDocKeywordSearchTool>;
|
||||
doc_read: ReturnType<typeof createDocReadTool>;
|
||||
doc_compose: ReturnType<typeof createDocComposeTool>;
|
||||
web_search_exa: ReturnType<typeof createExaSearchTool>;
|
||||
web_crawl_exa: ReturnType<typeof createExaCrawlTool>;
|
||||
code_artifact: ReturnType<typeof createCodeArtifactTool>;
|
||||
}
|
||||
|
||||
type ChunkType = TextStreamPart<CustomAITools>['type'];
|
||||
|
||||
export function toError(error: unknown): Error {
|
||||
@@ -451,6 +430,10 @@ export class TextStreamParser {
|
||||
);
|
||||
result = this.addPrefix(result);
|
||||
switch (chunk.toolName) {
|
||||
case 'conversation_summary': {
|
||||
result += `\nSummarizing context\n`;
|
||||
break;
|
||||
}
|
||||
case 'web_search_exa': {
|
||||
result += `\nSearching the web "${chunk.args.query}"\n`;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user