feat: enhance document processing with AI suggestions and preview image support
- Added AI_SUGGESTION event to DocumentEvent enum for improved document interaction. - Implemented updateDocumentPreviewImage mutation in DocumentSchema to allow updating of document preview images. - Integrated grammar checking functionality in DocumentService, utilizing OpenAI for real-time suggestions and caching results in Redis. - Enhanced MinioService with methods for file upsert and document content retrieval. - Updated PrismaTypes to include new relations and fields for better data structure alignment. - Commented out unused RESTful service methods for future cleanup. These changes improve the document editing experience by leveraging AI capabilities and enhancing the schema for better data management.
This commit is contained in:
@@ -3,9 +3,44 @@ import { Injectable, Logger } from '@nestjs/common'
|
||||
import { OpenAI } from 'openai'
|
||||
import { zodResponseFormat } from 'openai/helpers/zod'
|
||||
import Delta from 'quill-delta'
|
||||
import { z } from 'zod'
|
||||
|
||||
const DELTA_INSTRUCTIONS = ''
|
||||
export enum PromptType {
|
||||
CHECK_GRAMMAR = 'CHECK_GRAMMAR',
|
||||
REWRITE_TEXT = 'REWRITE_TEXT',
|
||||
SUMMARIZE = 'SUMMARIZE',
|
||||
TRANSLATE = 'TRANSLATE',
|
||||
EXPAND_CONTENT = 'EXPAND_CONTENT',
|
||||
}
|
||||
const prompts = {
|
||||
CHECK_GRAMMAR: `You will be provided with text delimited by triple quotes.
|
||||
If the text contains spell or grammar errors provide the text corrected.
|
||||
If the text does not contain errors return back the text delimited by triple quotes.
|
||||
\"\"\"{text}\"\"\"
|
||||
`,
|
||||
REWRITE_TEXT: `You will be provided with text delimited by triple quotes.
|
||||
Rewrite the text to improve clarity, conciseness, and overall readability.
|
||||
Maintain the original meaning and tone of the text.
|
||||
If the text is already well-written, return it as is.
|
||||
\"\"\"{text}\"\"\"
|
||||
`,
|
||||
SUMMARIZE: `You will be provided with text delimited by triple quotes.
|
||||
Create a concise summary that captures the key points and main ideas of the text.
|
||||
The summary should be clear, objective, and no longer than 3-4 sentences.
|
||||
\"\"\"{text}\"\"\"
|
||||
`,
|
||||
TRANSLATE: `You will be provided with text delimited by triple quotes and a target language.
|
||||
Translate the text accurately to the specified language, preserving the original tone and meaning.
|
||||
Provide the translation within triple quotes.
|
||||
Language: {language}
|
||||
\"\"\"{text}\"\"\"
|
||||
`,
|
||||
EXPAND_CONTENT: `You will be provided with text delimited by triple quotes.
|
||||
Expand on the given text by adding more details, examples, or explanations.
|
||||
Maintain the original style and intent of the text.
|
||||
Provide additional context that enhances understanding.
|
||||
\"\"\"{text}\"\"\"
|
||||
`,
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class OpenaiService {
|
||||
@@ -24,173 +59,30 @@ export class OpenaiService {
|
||||
return response.choices[0].message.content
|
||||
}
|
||||
|
||||
async documentSuggestEditDelta(documentDelta: Delta): Promise<Delta> {
|
||||
// Redefine the schema for Delta.Op with more detailed validations
|
||||
const deltaOpSchema = z
|
||||
.object({
|
||||
insert: z.string().optional(),
|
||||
delete: z.number().optional(),
|
||||
retain: z.number().optional(),
|
||||
attributes: z
|
||||
.object({
|
||||
bold: z.boolean().optional(),
|
||||
italic: z.boolean().optional(),
|
||||
color: z.string().optional(),
|
||||
link: z.string().optional(),
|
||||
header: z.number().optional(),
|
||||
// Add any other attributes that may be required here
|
||||
})
|
||||
.optional(),
|
||||
})
|
||||
.strict()
|
||||
|
||||
// Define the overall schema for Delta operations
|
||||
const schema = z.object({
|
||||
ops: z.array(deltaOpSchema),
|
||||
})
|
||||
|
||||
const systemPrompt = `
|
||||
System: You are an assistant tasked with editing document content in QuillJS Delta format. You will receive a document and editing instructions. Your goal is to modify the document while maintaining the exact **language**, **tone**, **structure**, and **intent** of the original content. Every modification must be consistent with the original style. Please follow the instructions meticulously and ensure all operations are precisely represented in Delta format.
|
||||
|
||||
1. **Document Content (Delta Format):**
|
||||
- The document content is provided in QuillJS Delta format. This is the **original** document content. Do not alter or change the language or tone of the original content unless specifically instructed.
|
||||
|
||||
---BEGIN---
|
||||
(Insert the original document content in Delta format here.)
|
||||
---END---
|
||||
|
||||
2. **Editing Instructions (Delta Format):**
|
||||
- Below are the instructions for editing the document. Follow these instructions strictly and ensure that changes are applied precisely as requested. Do not introduce new meanings or alter the context of the original document.
|
||||
|
||||
---BEGIN---
|
||||
(Insert detailed instructions here, specifying what text should be modified, added, deleted, or reformatted.)
|
||||
---END---
|
||||
|
||||
3. **Editing Requirements:**
|
||||
- **Language Consistency**: The document's language must remain consistent throughout. Do **not** introduce new phrasing, terms, or language that deviates from the original document's style or tone.
|
||||
- **Preserve the Intent**: Ensure that the intended meaning of the document is maintained. If the instructions suggest changes, they must fit within the overall context and tone of the original.
|
||||
- **Formatting and Structure**: Respect the original formatting and structural layout. Any modifications should adhere to the same format as the source document.
|
||||
- **Modification Representation**: All changes should be accurately reflected in **Delta format**, which includes:
|
||||
- **Insert**: For adding new text or content (e.g., images, links).
|
||||
- **Delete**: For removing content.
|
||||
- **Retain**: For keeping content but potentially modifying formatting or attributes.
|
||||
|
||||
4. **Web Browsing and Reference Suggestions:**
|
||||
- If applicable, suggest **web references** that are directly relevant to the content. If web browsing is required, ensure the reference links are **reliable**, **valid**, and fit seamlessly within the document's language.
|
||||
- When suggesting external links, make sure they are:
|
||||
- **Relevant** to the document's context.
|
||||
- **Formatted correctly** with proper citations.
|
||||
|
||||
5. **Delta Operations (Insert, Delete, Retain):**
|
||||
- Ensure that all modifications are represented by the appropriate **Delta operations**:
|
||||
- **Insert**: Add new content (text, images, etc.).
|
||||
- **Delete**: Remove content.
|
||||
- **Retain**: Keep content with no change, or only adjust its attributes.
|
||||
- All modifications should be **accurately** expressed using these operations.
|
||||
|
||||
6. **Handling Non-Text Content (Embeds):**
|
||||
- If there are changes to non-text elements (such as images, links, or videos), ensure they are added correctly using the **insert** operation with appropriate attributes (e.g., \`link\`, \`image\`).
|
||||
- Example:
|
||||
\`\`\`json
|
||||
{
|
||||
"ops": [
|
||||
{
|
||||
"insert": { "image": "https://example.com/image.png" },
|
||||
"attributes": { "link": "https://example.com" }
|
||||
}
|
||||
]
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
7. **Line and Paragraph Formatting:**
|
||||
- If changes involve formatting at the line or paragraph level (e.g., headings, lists, indentation), apply the appropriate **attributes**:
|
||||
- Example for adding a heading:
|
||||
\`\`\`json
|
||||
{
|
||||
"ops": [
|
||||
{ "insert": "New Heading" },
|
||||
{ "insert": "\\n", "attributes": { "header": 2 } }
|
||||
]
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
8. **Character Count and Delta Operations:**
|
||||
- Ensure that **Delta operations** correctly represent the changes to text length. Track the **character count** and ensure the Delta format reflects both the original and modified content accurately.
|
||||
|
||||
9. **Final Output:**
|
||||
- The **final output** must be a valid QuillJS Delta format document that:
|
||||
- Contains the necessary Delta operations (insert, delete, retain).
|
||||
- Reflects all modifications clearly and precisely, without altering the document’s original tone, intent, or structure.
|
||||
|
||||
10. **Additional Instructions for Handling Complex Edits:**
|
||||
- If the document requires complex edits (e.g., restructuring, replacing long sections of text), break the edits into smaller steps and ensure each step follows the same language and tone.
|
||||
|
||||
|
||||
|
||||
`
|
||||
const userPrompt = `
|
||||
User: I need you to edit the following document in QuillJS Delta format according to the instructions below.
|
||||
|
||||
1. **Document Content (Delta Format):**
|
||||
- Here is the document content in QuillJS Delta format. This is the **original** content of the document, and it must be preserved in **language, tone, and structure** unless specifically instructed otherwise.
|
||||
|
||||
---BEGIN---
|
||||
${JSON.stringify(documentDelta)}
|
||||
---END---
|
||||
|
||||
2. **Editing Instructions (Delta Format):**
|
||||
- Below are the detailed instructions for editing the content. Follow these instructions exactly as provided, ensuring that any changes made are in line with the original language and tone of the document.
|
||||
|
||||
---BEGIN---
|
||||
${DELTA_INSTRUCTIONS}
|
||||
---END---
|
||||
|
||||
3. **Requirements:**
|
||||
- **Language and Tone**: Do not deviate from the original language or tone. Any changes should be phrased in the same style and maintain the same level of formality, diction, and style.
|
||||
- **Preserve Intent**: Ensure that all edits preserve the original intent and meaning of the document. Avoid any rephrasing or changes that alter the message.
|
||||
- **Accurate Delta Representation**: Ensure all changes are accurately reflected in **Delta format**:
|
||||
- **Insert**: For new content.
|
||||
- **Delete**: For removed content.
|
||||
- **Retain**: For unchanged content with potential formatting changes.
|
||||
|
||||
4. **Web Browsing and Reference Suggestions:**
|
||||
- If needed, suggest **web references** that are relevant to the document's context. Only insert valid URLs with descriptions that complement the document's language and tone.
|
||||
|
||||
5. **Output:**
|
||||
- Provide the final **Delta format output** that accurately reflects all changes, including inserts, deletes, and retains, while maintaining consistency in language and tone.
|
||||
|
||||
6. **Delta Format Schema:**
|
||||
- Ensure the Delta format adheres to the following structure:
|
||||
- **Insert**: For adding new content (text, links, images, etc.).
|
||||
- **Delete**: For removing content.
|
||||
- **Retain**: For keeping content, but possibly modifying formatting or attributes.
|
||||
|
||||
7. **Handling Non-Text Embeds:**
|
||||
- For any non-text content, such as **images** or **videos**, use the appropriate **insert** operation with attributes. Ensure that any media links are formatted correctly and are relevant to the document’s content.
|
||||
`
|
||||
Logger.log(userPrompt, 'userPrompt')
|
||||
|
||||
async processText(text: string, sentenceIndex: number, prompt: PromptType) {
|
||||
const systemPrompt = 'You are an expert proofreader, the most advanced AI tool on the planet.'
|
||||
const userPrompt = prompts[prompt].replace('{text}', text)
|
||||
try {
|
||||
const response = await this.openai.chat.completions.create({
|
||||
model: 'gpt-4o',
|
||||
model: 'claude-3-haiku-20240307',
|
||||
messages: [
|
||||
{ role: 'system', content: systemPrompt },
|
||||
{ role: 'user', content: userPrompt },
|
||||
],
|
||||
response_format: zodResponseFormat(schema, 'Delta'),
|
||||
})
|
||||
|
||||
const result = JSON.parse(response.choices[0].message.content ?? '') as Delta
|
||||
|
||||
// Validate that the result matches the expected structure
|
||||
schema.parse(result)
|
||||
|
||||
Logger.log(result, 'result')
|
||||
return result
|
||||
const result = response.choices[0].message.content
|
||||
// split to get data only in triple quotes
|
||||
const resultData = result?.split('"""')[1]
|
||||
Logger.log(resultData, 'result')
|
||||
return {
|
||||
sentenceIndex,
|
||||
result: resultData,
|
||||
}
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
} catch (error: any) {
|
||||
Logger.error(`Error in Delta processing: ${error.message}`, 'OpenaiService')
|
||||
throw new Error('Failed to process Delta changes.')
|
||||
Logger.error(`Error in text processing: ${error.message}`, 'OpenaiService')
|
||||
throw new Error('Failed to process data')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user