mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 05:14:54 +00:00
feat(core): support compose a doc tool (#13013)
#### PR Dependency Tree * **PR #13013** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Introduced a document composition tool for AI chat, allowing users to generate, preview, and save structured markdown documents directly from chat interactions. * Added an artifact preview panel for enhanced document previews within the chat interface. * Enabled dynamic content rendering in the chat panel's right section for richer user experiences. * **Improvements** * Sidebar maximum width increased for greater workspace flexibility. * Enhanced chat message and split view styling for improved layout and usability. * **Bug Fixes** * None. * **Other** * Registered new custom elements for AI tools and artifact preview functionality. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -1752,6 +1752,7 @@ Below is the user's query. Please respond in the user's preferred language witho
|
||||
'docKeywordSearch',
|
||||
'docSemanticSearch',
|
||||
'webSearch',
|
||||
'docCompose',
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
buildDocContentGetter,
|
||||
buildDocKeywordSearchGetter,
|
||||
buildDocSearchGetter,
|
||||
createDocComposeTool,
|
||||
createDocEditTool,
|
||||
createDocKeywordSearchTool,
|
||||
createDocReadTool,
|
||||
@@ -198,6 +199,10 @@ export abstract class CopilotProvider<C = any> {
|
||||
tools.web_crawl_exa = createExaCrawlTool(this.AFFiNEConfig);
|
||||
break;
|
||||
}
|
||||
case 'docCompose': {
|
||||
tools.doc_compose = createDocComposeTool();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return tools;
|
||||
|
||||
@@ -69,6 +69,8 @@ export const PromptConfigStrictSchema = z.object({
|
||||
'docSemanticSearch',
|
||||
// work with exa/model internal tools
|
||||
'webSearch',
|
||||
// artifact tools
|
||||
'docCompose',
|
||||
])
|
||||
.array()
|
||||
.nullable()
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
import { ZodType } from 'zod';
|
||||
|
||||
import {
|
||||
createDocComposeTool,
|
||||
createDocEditTool,
|
||||
createDocKeywordSearchTool,
|
||||
createDocReadTool,
|
||||
@@ -388,6 +389,7 @@ export interface CustomAITools extends ToolSet {
|
||||
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>;
|
||||
}
|
||||
@@ -457,6 +459,10 @@ export class TextStreamParser {
|
||||
result += `\nReading the doc "${chunk.args.doc_id}"\n`;
|
||||
break;
|
||||
}
|
||||
case 'doc_compose': {
|
||||
result += `\nWriting document "${chunk.args.title}"\n`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = this.markAsCallout(result);
|
||||
break;
|
||||
@@ -486,6 +492,16 @@ export class TextStreamParser {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'doc_compose': {
|
||||
if (
|
||||
chunk.result &&
|
||||
typeof chunk.result === 'object' &&
|
||||
'title' in chunk.result
|
||||
) {
|
||||
result += `\nDocument "${chunk.result.title}" created successfully with ${chunk.result.wordCount} words.\n`;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'web_search_exa': {
|
||||
if (Array.isArray(chunk.result)) {
|
||||
result += `\n${this.getWebSearchLinks(chunk.result)}\n`;
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { tool } from 'ai';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { toolError } from './error';
|
||||
|
||||
const logger = new Logger('DocComposeTool');
|
||||
|
||||
export const createDocComposeTool = () => {
|
||||
return tool({
|
||||
description:
|
||||
'Write a new document with markdown content. This tool creates structured markdown content for documents including titles, sections, and formatting.',
|
||||
parameters: z.object({
|
||||
title: z.string().describe('The title of the document'),
|
||||
content: z
|
||||
.string()
|
||||
.describe(
|
||||
'The main content to write in markdown format. Include proper markdown formatting like headers (# ## ###), lists (- * 1.), links [text](url), code blocks ```code```, and other markdown elements as needed.'
|
||||
),
|
||||
sections: z
|
||||
.array(
|
||||
z.object({
|
||||
heading: z.string().describe('Section heading'),
|
||||
content: z.string().describe('Section content in markdown'),
|
||||
})
|
||||
)
|
||||
.optional()
|
||||
.describe('Optional structured sections for the document'),
|
||||
metadata: z
|
||||
.object({
|
||||
tags: z
|
||||
.array(z.string())
|
||||
.optional()
|
||||
.describe('Optional tags for the document'),
|
||||
description: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe('Optional brief description of the document'),
|
||||
})
|
||||
.optional()
|
||||
.describe('Optional metadata for the document'),
|
||||
}),
|
||||
execute: async ({ title, content, sections, metadata }) => {
|
||||
try {
|
||||
let markdownContent = '';
|
||||
|
||||
markdownContent += `${content}\n\n`;
|
||||
|
||||
if (sections && sections.length > 0) {
|
||||
for (const section of sections) {
|
||||
markdownContent += `## ${section.heading}\n\n`;
|
||||
markdownContent += `${section.content}\n\n`;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
title,
|
||||
markdown: markdownContent.trim(),
|
||||
wordCount: content.split(/\s+/).length,
|
||||
metadata: metadata || {},
|
||||
tags: metadata?.tags || [],
|
||||
description: metadata?.description || '',
|
||||
};
|
||||
} catch (err: any) {
|
||||
logger.error(`Failed to write document: ${title}`, err);
|
||||
return toolError('Doc Write Failed', err.message);
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './doc-compose';
|
||||
export * from './doc-edit';
|
||||
export * from './doc-keyword-search';
|
||||
export * from './doc-read';
|
||||
|
||||
Reference in New Issue
Block a user