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:
DarkSky
2026-08-10 09:27:58 +08:00
committed by GitHub
parent 42322d13fe
commit ee899a267b
311 changed files with 20468 additions and 14806 deletions

View File

@@ -24,7 +24,6 @@ import {
checkCanaryDateClientVersion,
DocNotFound,
DocUpdateBlocked,
EventBus,
GatewayErrorWrapper,
metrics,
NotInSpace,
@@ -32,6 +31,7 @@ import {
SpaceAccessDenied,
} from '../../base';
import { Models } from '../../models';
import { authorizeUserdataDocSubject } from '../../native';
import { CurrentUser } from '../auth';
import {
DocReader,
@@ -226,7 +226,6 @@ export class SpaceSyncGateway
constructor(
private readonly ac: PermissionAccess,
private readonly event: EventBus,
private readonly workspace: PgWorkspaceDocStorageAdapter,
private readonly userspace: PgUserspaceDocStorageAdapter,
private readonly docReader: DocReader,
@@ -332,6 +331,20 @@ export class SpaceSyncGateway
await this.ac.user(userId).doc(spaceId, docId).assert(action);
}
private assertUserdataSubject(
spaceType: SpaceType,
userId: string,
workspaceId: string,
docId: string
) {
if (
spaceType === SpaceType.Workspace &&
!authorizeUserdataDocSubject(userId, workspaceId, docId)
) {
throw new SpaceAccessDenied({ spaceId: workspaceId });
}
}
handleConnection(client: Socket) {
this.connectionCount++;
this.logger.debug(`New connection, total: ${this.connectionCount}`);
@@ -599,10 +612,6 @@ export class SpaceSyncGateway
return { data: { clientId: client.id, success: false } };
}
if (spaceType === SpaceType.Workspace) {
this.event.emit('workspace.embedding', { workspaceId: spaceId });
}
const adapter = this.selectAdapter(client, spaceType);
await adapter.join(user.id, spaceId);
@@ -644,6 +653,7 @@ export class SpaceSyncGateway
const id = new DocID(docId, spaceId);
const adapter = this.selectAdapter(client, spaceType);
adapter.assertIn(spaceId);
this.assertUserdataSubject(spaceType, user.id, spaceId, id.guid);
await this.assertDocActionAllowed(
spaceType,
user.id,
@@ -678,6 +688,7 @@ export class SpaceSyncGateway
@MessageBody() { spaceType, spaceId, docId }: DeleteDocMessage
): Promise<EventResponse<{ success: true }>> {
const adapter = this.selectAdapter(client, spaceType);
this.assertUserdataSubject(spaceType, user.id, spaceId, docId);
await this.assertDocActionAllowed(
spaceType,
user.id,
@@ -702,7 +713,8 @@ export class SpaceSyncGateway
const { spaceType, spaceId, docId, update } = message;
const adapter = this.selectAdapter(client, spaceType);
// Quota recovery mode is intentionally not applied to sync in this phase.
// Quota recovery mode is intentionally not applied to sync.
this.assertUserdataSubject(spaceType, user.id, spaceId, docId);
await this.assertDocActionAllowed(
spaceType,
user.id,