mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-11 20:08:37 +00:00
refactor: move chat block to affine (#8368)
[BS-898](https://linear.app/affine-design/issue/BS-898/move-ai-chat-block-to-affine) Should be merged after https://github.com/toeverything/blocksuite/pull/8420 merged and bumped.
This commit is contained in:
2
packages/common/env/package.json
vendored
2
packages/common/env/package.json
vendored
@@ -3,7 +3,7 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"@blocksuite/affine": "0.17.18",
|
||||
"@blocksuite/affine": "0.17.19",
|
||||
"vitest": "2.1.1"
|
||||
},
|
||||
"exports": {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"@affine/debug": "workspace:*",
|
||||
"@affine/env": "workspace:*",
|
||||
"@affine/templates": "workspace:*",
|
||||
"@blocksuite/affine": "0.17.18",
|
||||
"@blocksuite/affine": "0.17.19",
|
||||
"@datastructures-js/binary-search-tree": "^5.3.2",
|
||||
"foxact": "^0.2.33",
|
||||
"fractional-indexing": "^3.2.0",
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import { GfxCompatible } from '@blocksuite/affine/block-std/gfx';
|
||||
import type { SerializedXYWH } from '@blocksuite/affine/global/utils';
|
||||
import { BlockModel, defineBlockSchema } from '@blocksuite/affine/store';
|
||||
|
||||
type AIChatProps = {
|
||||
xywh: SerializedXYWH;
|
||||
index: string;
|
||||
scale: number;
|
||||
messages: string; // JSON string of ChatMessage[]
|
||||
sessionId: string; // forked session id
|
||||
rootWorkspaceId: string; // workspace id of root chat session
|
||||
rootDocId: string; // doc id of root chat session
|
||||
};
|
||||
|
||||
export const AIChatBlockSchema = defineBlockSchema({
|
||||
flavour: 'affine:embed-ai-chat',
|
||||
props: (): AIChatProps => ({
|
||||
xywh: '[0,0,0,0]',
|
||||
index: 'a0',
|
||||
scale: 1,
|
||||
messages: '',
|
||||
sessionId: '',
|
||||
rootWorkspaceId: '',
|
||||
rootDocId: '',
|
||||
}),
|
||||
metadata: {
|
||||
version: 1,
|
||||
role: 'content',
|
||||
children: [],
|
||||
},
|
||||
toModel: () => {
|
||||
return new AIChatBlockModel();
|
||||
},
|
||||
});
|
||||
|
||||
export class AIChatBlockModel extends GfxCompatible<AIChatProps>(BlockModel) {}
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
namespace BlockSuite {
|
||||
interface EdgelessBlockModelMap {
|
||||
'affine:embed-ai-chat': AIChatBlockModel;
|
||||
}
|
||||
interface BlockModels {
|
||||
'affine:embed-ai-chat': AIChatBlockModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export const CHAT_BLOCK_WIDTH = 300;
|
||||
export const CHAT_BLOCK_HEIGHT = 320;
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from './ai-chat-model';
|
||||
export * from './consts';
|
||||
export * from './types';
|
||||
@@ -0,0 +1,25 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
// Define the Zod schema
|
||||
const ChatMessageSchema = z.object({
|
||||
id: z.string(),
|
||||
content: z.string(),
|
||||
role: z.union([z.literal('user'), z.literal('assistant')]),
|
||||
createdAt: z.string(),
|
||||
attachments: z.array(z.string()).optional(),
|
||||
userId: z.string().optional(),
|
||||
userName: z.string().optional(),
|
||||
avatarUrl: z.string().optional(),
|
||||
});
|
||||
|
||||
export const ChatMessagesSchema = z.array(ChatMessageSchema);
|
||||
|
||||
// Derive the TypeScript type from the Zod schema
|
||||
export type ChatMessage = z.infer<typeof ChatMessageSchema>;
|
||||
|
||||
export type MessageRole = 'user' | 'assistant';
|
||||
export type MessageUserInfo = {
|
||||
userId?: string;
|
||||
userName?: string;
|
||||
avatarUrl?: string;
|
||||
};
|
||||
1
packages/common/infra/src/blocksuite/blocks/index.ts
Normal file
1
packages/common/infra/src/blocksuite/blocks/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './ai-chat-block';
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './blocks';
|
||||
export {
|
||||
migratePages as forceUpgradePages,
|
||||
migrateGuidCompatibility,
|
||||
|
||||
@@ -30,7 +30,7 @@ export function initDocFromProps(doc: Doc, props?: DocProps) {
|
||||
'affine:page',
|
||||
props?.page || { title: new Text('') }
|
||||
);
|
||||
doc.addBlock('affine:surface', props?.surface || {}, pageBlockId);
|
||||
doc.addBlock('affine:surface' as never, props?.surface || {}, pageBlockId);
|
||||
const noteBlockId = doc.addBlock(
|
||||
'affine:note',
|
||||
{
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { Unreachable } from '@affine/env/constant';
|
||||
import { type DocMode } from '@blocksuite/affine/blocks';
|
||||
import {
|
||||
type AffineTextAttributes,
|
||||
type DocMode,
|
||||
} from '@blocksuite/affine/blocks';
|
||||
import type { DeltaInsert } from '@blocksuite/affine/inline';
|
||||
|
||||
import { Service } from '../../../framework';
|
||||
import { type DocProps, initDocFromProps } from '../../../initialization';
|
||||
@@ -77,7 +81,7 @@ export class DocsService extends Service {
|
||||
const { doc, release } = this.open(targetDocId);
|
||||
doc.setPriorityLoad(10);
|
||||
await doc.waitForSyncReady();
|
||||
const text = doc.blockSuiteDoc.Text.fromDelta([
|
||||
const text = new doc.blockSuiteDoc.Text([
|
||||
{
|
||||
insert: ' ',
|
||||
attributes: {
|
||||
@@ -87,7 +91,7 @@ export class DocsService extends Service {
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
] as DeltaInsert<AffineTextAttributes>[]);
|
||||
const [frame] = doc.blockSuiteDoc.getBlocksByFlavour('affine:note');
|
||||
frame &&
|
||||
doc.blockSuiteDoc.addBlock(
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { AffineSchemas } from '@blocksuite/affine/blocks/schemas';
|
||||
import { AIChatBlockSchema } from '@blocksuite/affine/presets';
|
||||
import { Schema } from '@blocksuite/affine/store';
|
||||
|
||||
import { AIChatBlockSchema } from '../../blocksuite/blocks/ai-chat-block/ai-chat-model';
|
||||
|
||||
let _schema: Schema | null = null;
|
||||
export function getAFFiNEWorkspaceSchema() {
|
||||
if (!_schema) {
|
||||
|
||||
Reference in New Issue
Block a user