mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-18 02:21:51 +08:00
feat(server): improve context management (#15448)
#### PR Dependency Tree * **PR #15448** 👈 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** * Added workspace artifact upload, browsing, removal, deduplication, and library ownership support. * Copilot now supports scoped document and artifact search, canvas reading, live editor context, and frontend tools. * Added scope and focus selectors with source-resolution receipts in chat. * Added embedding health, progress, synchronization, and retrieval capabilities. * Added BYOK policy visibility, provider restrictions, endpoint dialect selection, and validation. * Added delegated editor interactions and userdata document authorization. * **Bug Fixes** * Improved attachment handling, cancellation, access control, retrieval fallbacks, workspace synchronization, and configuration validation. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -18,6 +18,37 @@ import type {
|
||||
import type { GfxModel } from '@blocksuite/std/gfx';
|
||||
import { type Page } from '@playwright/test';
|
||||
export class EditorUtils {
|
||||
public static async waitForCurrentDocSynced(page: Page) {
|
||||
await page.evaluate(async () => {
|
||||
const [, , workspaceId, docId] = location.pathname.split('/');
|
||||
const workspace = (
|
||||
window as typeof window & {
|
||||
currentWorkspace?: {
|
||||
engine: {
|
||||
doc: {
|
||||
waitForSynced(docId: string, abort: AbortSignal): Promise<void>;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
).currentWorkspace;
|
||||
if (!workspaceId || !docId || !workspace) {
|
||||
throw new Error('Current document is unavailable');
|
||||
}
|
||||
const abort = AbortSignal.timeout(60_000);
|
||||
await Promise.all([
|
||||
workspace.engine.doc.waitForSynced(docId, abort),
|
||||
workspace.engine.doc.waitForSynced('db$docProperties', abort),
|
||||
]);
|
||||
const response = await fetch(
|
||||
`/api/workspaces/${workspaceId}/docs/${docId}`
|
||||
);
|
||||
if (!response.ok) {
|
||||
throw new Error('Current document could not be persisted');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static async focusToEditor(page: Page) {
|
||||
const title = getBlockSuiteEditorTitle(page);
|
||||
await title.focus();
|
||||
@@ -351,8 +382,7 @@ export class EditorUtils {
|
||||
await page.keyboard.press('Enter');
|
||||
}
|
||||
}
|
||||
// sleep 1 sec to wait the doc sync
|
||||
await page.waitForTimeout(1000);
|
||||
await this.waitForCurrentDocSynced(page);
|
||||
}
|
||||
|
||||
public static async createTagAndDoc(
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { cleanupWorkspace, runPrisma } from '@affine-test/kit/utils/cloud';
|
||||
import { expect, type Page } from '@playwright/test';
|
||||
|
||||
const WORKSPACE_EMBEDDING_SWITCH_TEST_ID = 'workspace-embedding-setting-switch';
|
||||
@@ -95,7 +94,7 @@ export class SettingsPanelUtils {
|
||||
|
||||
await page
|
||||
.getByTestId('workspace-embedding-setting-attachment-uploading-item')
|
||||
.waitFor({ state: 'hidden' });
|
||||
.waitFor({ state: 'hidden', timeout: 30_000 });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +225,6 @@ export class SettingsPanelUtils {
|
||||
timeout: number,
|
||||
status = 'synced'
|
||||
) {
|
||||
await cleanupWorkspace(page.url().split('/').slice(-2)[0] || '');
|
||||
await expect(async () => {
|
||||
await this.openSettingsPanel(page);
|
||||
const title = page.getByTestId('embedding-progress-title');
|
||||
@@ -266,17 +264,17 @@ export class SettingsPanelUtils {
|
||||
'workspace-embedding-setting-attachment-item'
|
||||
);
|
||||
await expect(attachmentItems).toHaveCount(expectedFileCount);
|
||||
await expect(
|
||||
attachmentList.getByTestId(
|
||||
'workspace-embedding-setting-attachment-uploading-item'
|
||||
)
|
||||
).toHaveCount(0);
|
||||
}).toPass({ timeout });
|
||||
|
||||
const workspaceId = page.url().split('/').slice(-2)[0] || '';
|
||||
await cleanupWorkspace(workspaceId);
|
||||
await expect(async () => {
|
||||
const embeddedFileCount = await runPrisma(client =>
|
||||
client.aiWorkspaceFiles.count({
|
||||
where: { workspaceId, embeddings: { some: {} } },
|
||||
})
|
||||
);
|
||||
expect(embeddedFileCount).toBe(expectedFileCount);
|
||||
await expect(
|
||||
page.getByTestId('workspace-embedding-setting-attachment-ready-item')
|
||||
).toHaveCount(expectedFileCount);
|
||||
}).toPass({ timeout });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,16 +58,8 @@ export class TestUtils {
|
||||
await waitForEditorLoad(page);
|
||||
}
|
||||
|
||||
public async setupTestEnvironment(page: Page, defaultModel?: string) {
|
||||
const selectedModel = defaultModel ?? 'gpt-5.6-luna';
|
||||
|
||||
public async setupTestEnvironment(page: Page) {
|
||||
await skipOnboarding(page.context());
|
||||
await page.context().addInitScript(model => {
|
||||
window.localStorage.setItem(
|
||||
'global-state:AIModelId',
|
||||
JSON.stringify(model)
|
||||
);
|
||||
}, selectedModel);
|
||||
await openHomePage(page);
|
||||
await this.createNewPage(page);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user