Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,16 @@ English | [中文](./README_zh.md)

## 💡 What's New

**🚀 3.8 Sandbox Environment!**
**🚀 3.9 Enhanced Multi-Agent Collaboration!**

XpertAI 3.9 introduces enhanced multi-agent collaboration capabilities, allowing agents to work together more effectively on complex tasks. Key features include:

- **Agent Team Composition**: Create specialized agent teams with predefined roles and responsibilities
- **Task Decomposition**: Automatic task breakdown and distribution among team members
- **Collaborative Decision Making**: Agents can share insights and coordinate decisions
- **Progress Sync**: Real-time progress synchronization between collaborating agents

**🚀 3.8 Sandbox Environment!****

XpertAI 3.8 releases the Agent Sandbox feature, providing an isolated execution and file operation environment for agents. One of the core capabilities of the sandbox plugin is the provider plugin mechanism. Through custom providers, you can integrate different runtime infrastructures, such as:

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "xpert.ai",
"version": "3.0",
"version": "3.9",
"description": "",
"license": "AGPL-3.0",
"homepage": "https://xpertai.cn",
Expand Down
67 changes: 44 additions & 23 deletions packages/server-ai/src/knowledge-document/document.subscriber.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,52 @@
import { DocumentTypeEnum } from '@metad/contracts'
import { EntitySubscriberInterface, EventSubscriber, InsertEvent } from 'typeorm'
import { StorageFile } from '@metad/server-core'
import { EntitySubscriberInterface, EventSubscriber, InsertEvent, LoadEvent } from 'typeorm'
import { Knowledgebase } from '../core/entities/internal'
import { KnowledgeDocument } from './document.entity'
import { FileStorage } from '@metad/server-core'

@EventSubscriber()
export class KnowledgeDocumentSubscriber implements EntitySubscriberInterface<KnowledgeDocument> {
/**
* Specify the entity type to monitor
*/
listenTo() {
return KnowledgeDocument
}
/**
* Specify the entity type to monitor
*/
listenTo() {
return KnowledgeDocument
}

/**
* Increment the document count when creating a file
*
* @param event
*/
async beforeInsert(event: InsertEvent<KnowledgeDocument>) {
if (event.entity.sourceType !== DocumentTypeEnum.FOLDER) {
const kbRepo = event.queryRunner.manager.getRepository(Knowledgebase)
const kb = await kbRepo.findOneBy({ id: event.entity.knowledgebaseId })
if (kb) {
kb.documentNum ??= 0
kb.documentNum += 1
await kbRepo.save(kb)
}
}
}
/**
* Increment the document count when creating a file
*
* @param event
*/
async beforeInsert(event: InsertEvent<KnowledgeDocument>) {
if (event.entity.sourceType !== DocumentTypeEnum.FOLDER) {
const kbRepo = event.queryRunner.manager.getRepository(Knowledgebase)
const kb = await kbRepo.findOne({ where: { id: event.entity.knowledgebaseId } })
if (kb) {
kb.documentNum ??= 0
kb.documentNum += 1
await kbRepo.save(kb)
}
}
}

/**
* Populate fileUrl from StorageFile when loading document
*
* @param entity
* @param event
*/
async afterLoad(entity: KnowledgeDocument, event?: LoadEvent<KnowledgeDocument>): Promise<void> {
if (entity instanceof KnowledgeDocument && entity.storageFileId && !entity.fileUrl) {
const storageFile = await event.manager.findOne(StorageFile, {
where: { id: entity.storageFileId },
select: ['id', 'file', 'storageProvider']
})
if (storageFile?.file && storageFile.storageProvider) {
const store = new FileStorage().setProvider(storageFile.storageProvider)
entity.fileUrl = store.getProviderInstance().url(storageFile.file)
}
}
}
}