mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-16 09:36:17 +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:
@@ -0,0 +1,76 @@
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { tool } from 'ai';
|
||||
import { z } from 'zod';
|
||||
|
||||
import type { PromptService } from '../prompt';
|
||||
import type { CopilotProviderFactory } from '../providers';
|
||||
import { toolError } from './error';
|
||||
|
||||
const logger = new Logger('ConversationSummaryTool');
|
||||
|
||||
export const createConversationSummaryTool = (
|
||||
sessionId: string | undefined,
|
||||
promptService: PromptService,
|
||||
factory: CopilotProviderFactory
|
||||
) => {
|
||||
return tool({
|
||||
description:
|
||||
'Create a concise, AI-generated summary of the conversation so far—capturing key topics, decisions, and critical details. Use this tool whenever the context becomes lengthy to preserve essential information that might otherwise be lost to truncation in future turns.',
|
||||
parameters: z.object({
|
||||
focus: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe(
|
||||
'Optional focus area for the summary (e.g., "technical decisions", "user requirements", "project status")'
|
||||
),
|
||||
length: z
|
||||
.enum(['brief', 'detailed', 'comprehensive'])
|
||||
.default('detailed')
|
||||
.describe(
|
||||
'The desired length of the summary: brief (1-2 sentences), detailed (paragraph), comprehensive (multiple paragraphs)'
|
||||
),
|
||||
}),
|
||||
execute: async ({ focus, length }, { messages }) => {
|
||||
try {
|
||||
if (!messages || messages.length === 0) {
|
||||
return toolError(
|
||||
'No Conversation Context',
|
||||
'No messages available to summarize'
|
||||
);
|
||||
}
|
||||
|
||||
const prompt = await promptService.get('Conversation Summary');
|
||||
const provider = await factory.getProviderByModel(prompt?.model || '');
|
||||
|
||||
if (!prompt || !provider) {
|
||||
return toolError(
|
||||
'Prompt Not Found',
|
||||
'Failed to summarize conversation.'
|
||||
);
|
||||
}
|
||||
|
||||
const summary = await provider.text(
|
||||
{ modelId: prompt.model },
|
||||
prompt.finish({
|
||||
messages: messages.map(m => ({
|
||||
...m,
|
||||
content: m.content.toString(),
|
||||
})),
|
||||
focus: focus || 'general',
|
||||
length,
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
focusArea: focus || 'general',
|
||||
messageCount: messages.length,
|
||||
summary,
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
} catch (err: any) {
|
||||
logger.error(`Failed to summarize conversation (${sessionId})`, err);
|
||||
return toolError('Conversation Summary Failed', err.message);
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -1,4 +1,29 @@
|
||||
import { ToolSet } from 'ai';
|
||||
|
||||
import { createCodeArtifactTool } from './code-artifact';
|
||||
import { createConversationSummaryTool } from './conversation-summary';
|
||||
import { createDocComposeTool } from './doc-compose';
|
||||
import { createDocEditTool } from './doc-edit';
|
||||
import { createDocKeywordSearchTool } from './doc-keyword-search';
|
||||
import { createDocReadTool } from './doc-read';
|
||||
import { createDocSemanticSearchTool } from './doc-semantic-search';
|
||||
import { createExaCrawlTool } from './exa-crawl';
|
||||
import { createExaSearchTool } from './exa-search';
|
||||
|
||||
export interface CustomAITools extends ToolSet {
|
||||
code_artifact: ReturnType<typeof createCodeArtifactTool>;
|
||||
conversation_summary: ReturnType<typeof createConversationSummaryTool>;
|
||||
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>;
|
||||
}
|
||||
|
||||
export * from './code-artifact';
|
||||
export * from './conversation-summary';
|
||||
export * from './doc-compose';
|
||||
export * from './doc-edit';
|
||||
export * from './doc-keyword-search';
|
||||
|
||||
Reference in New Issue
Block a user