feat(server): trigger workspace embedding (#12328)

fix AI-127

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added automated event handling for workspace updates and document embedding, streamlining document embedding workflows.
  - Introduced detection and queuing of documents needing embedding, excluding ignored documents.
- **Improvements**
  - Enhanced performance of embedding-related searches by filtering results at the database level.
  - Increased concurrency for embedding job processing to improve throughput.
- **Bug Fixes**
  - Improved error handling and fallback for missing document titles during embedding.
  - Added safeguards to skip invalid embedding jobs based on document identifiers.
- **Tests**
  - Expanded test coverage for document embedding and ignored document filtering.
  - Updated end-to-end tests to use dynamic content for improved reliability.
  - Added synchronization waits in document creation utilities to improve test stability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
darkskygit
2025-05-20 05:16:45 +00:00
parent 3c982d2b91
commit 6f9361caee
13 changed files with 213 additions and 35 deletions
@@ -22,19 +22,23 @@ test.describe('AIChatWith/Collections', () => {
loggedInPage: page,
utils,
}) => {
const randomStr = Math.random().toString(36).substring(2, 6);
// Create two collections
await utils.editor.createCollectionAndDoc(
page,
'Collection 1',
'CollectionAAaa is a cute dog'
`Collection${randomStr} is a cute dog`
);
await utils.chatPanel.chatWithCollections(page, ['Collection 1']);
await utils.chatPanel.makeChat(page, 'What is CollectionAAaa(Use English)');
await utils.chatPanel.makeChat(
page,
`What is Collection${randomStr}(Use English)`
);
await utils.chatPanel.waitForHistory(page, [
{
role: 'user',
content: 'What is CollectionAAaa(Use English)',
content: `What is Collection${randomStr}(Use English)`,
},
{
role: 'assistant',
@@ -45,7 +49,7 @@ test.describe('AIChatWith/Collections', () => {
await expect(async () => {
const { content, message } =
await utils.chatPanel.getLatestAssistantMessage(page);
expect(content).toMatch(/CollectionAAaa.*dog/);
expect(content).toMatch(new RegExp(`Collection${randomStr}.*dog`));
expect(await message.locator('affine-footnote-node').count()).toBe(1);
}).toPass();
});
@@ -54,17 +58,19 @@ test.describe('AIChatWith/Collections', () => {
loggedInPage: page,
utils,
}) => {
const randomStr1 = Math.random().toString(36).substring(2, 6);
const randomStr2 = Math.random().toString(36).substring(2, 6);
// Create two collections
await utils.editor.createCollectionAndDoc(
page,
'Collection 2',
'CollectionEEee is a cute cat'
`Collection${randomStr1} is a cute cat`
);
await utils.editor.createCollectionAndDoc(
page,
'Collection 3',
'CollectionFFff is a cute dog'
`Collection${randomStr2} is a cute dog`
);
await utils.chatPanel.chatWithCollections(page, [
@@ -73,12 +79,12 @@ test.describe('AIChatWith/Collections', () => {
]);
await utils.chatPanel.makeChat(
page,
'What is CollectionEEee? What is CollectionFFff?(Use English)'
`What is Collection${randomStr1}? What is Collection${randomStr2}?(Use English)`
);
await utils.chatPanel.waitForHistory(page, [
{
role: 'user',
content: 'What is CollectionEEee? What is CollectionFFff?(Use English)',
content: `What is Collection${randomStr1}? What is Collection${randomStr2}?(Use English)`,
},
{
role: 'assistant',
@@ -89,8 +95,8 @@ test.describe('AIChatWith/Collections', () => {
await expect(async () => {
const { content, message } =
await utils.chatPanel.getLatestAssistantMessage(page);
expect(content).toMatch(/CollectionEEee.*cat/);
expect(content).toMatch(/CollectionFFff.*dog/);
expect(content).toMatch(new RegExp(`Collection${randomStr1}.*cat`));
expect(content).toMatch(new RegExp(`Collection${randomStr2}.*dog`));
expect(await message.locator('affine-footnote-node').count()).toBe(2);
}).toPass();
});
@@ -20,13 +20,21 @@ test.describe('AIChatWith/tags', () => {
loggedInPage: page,
utils,
}) => {
await utils.editor.createTagAndDoc(page, 'Tag 1', 'TagAAaa is a cute cat');
const randomStr = Math.random().toString(36).substring(2, 6);
await utils.editor.createTagAndDoc(
page,
'Tag 1',
`Tag${randomStr} is a cute cat`
);
await utils.chatPanel.chatWithTags(page, ['Tag 1']);
await utils.chatPanel.makeChat(page, 'What is TagAAaa(Use English)');
await utils.chatPanel.makeChat(
page,
`What is Tag${randomStr}(Use English)`
);
await utils.chatPanel.waitForHistory(page, [
{
role: 'user',
content: 'What is TagAAaa(Use English)',
content: `What is Tag${randomStr}(Use English)`,
},
{
role: 'assistant',
@@ -36,7 +44,7 @@ test.describe('AIChatWith/tags', () => {
await expect(async () => {
const { content, message } =
await utils.chatPanel.getLatestAssistantMessage(page);
expect(content).toMatch(/TagAAaa.*cat/);
expect(content).toMatch(new RegExp(`Tag${randomStr}.*cat`));
await expect(message.locator('affine-footnote-node')).toHaveCount(1);
}).toPass();
});
@@ -45,17 +53,28 @@ test.describe('AIChatWith/tags', () => {
loggedInPage: page,
utils,
}) => {
await utils.editor.createTagAndDoc(page, 'Tag 2', 'TagEEee is a cute cat');
await utils.editor.createTagAndDoc(page, 'Tag 3', 'TagFFff is a cute dog');
const randomStr1 = Math.random().toString(36).substring(2, 6);
const randomStr2 = Math.random().toString(36).substring(2, 6);
await utils.editor.createTagAndDoc(
page,
'Tag 2',
`Tag${randomStr1} is a cute cat`
);
await utils.editor.createTagAndDoc(
page,
'Tag 3',
`Tag${randomStr2} is a cute dog`
);
await utils.chatPanel.chatWithTags(page, ['Tag 2', 'Tag 3']);
await utils.chatPanel.makeChat(
page,
'What is TagEEee? What is TagFFff?(Use English)'
`What is Tag${randomStr1}? What is Tag${randomStr2}?(Use English)`
);
await utils.chatPanel.waitForHistory(page, [
{
role: 'user',
content: 'What is TagEEee? What is TagFFff?(Use English)',
content: `What is Tag${randomStr1}? What is Tag${randomStr2}?(Use English)`,
},
{
role: 'assistant',
@@ -65,8 +84,8 @@ test.describe('AIChatWith/tags', () => {
await expect(async () => {
const { content, message } =
await utils.chatPanel.getLatestAssistantMessage(page);
expect(content).toMatch(/TagEEee.*cat/);
expect(content).toMatch(/TagFFff.*dog/);
expect(content).toMatch(new RegExp(`Tag${randomStr1}.*cat`));
expect(content).toMatch(new RegExp(`Tag${randomStr2}.*dog`));
await expect(message.locator('affine-footnote-node')).toHaveCount(2);
}).toPass();
});
@@ -334,6 +334,8 @@ export class EditorUtils {
await page.keyboard.press('Enter');
}
}
// sleep 1 sec to wait the doc sync
await page.waitForTimeout(1000);
}
public static async createTagAndDoc(
@@ -362,6 +364,8 @@ export class EditorUtils {
await page.keyboard.press('Enter');
}
}
// sleep 1 sec to wait the doc sync
await page.waitForTimeout(1000);
}
public static async selectElementInEdgeless(page: Page, elements: string[]) {