mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 21:27:20 +00:00
feat: adapt workflow for ppt & minimap (#7464)
This commit is contained in:
@@ -149,15 +149,18 @@ export class CopilotClient {
|
||||
}
|
||||
|
||||
// Text or image to text
|
||||
chatTextStream({
|
||||
sessionId,
|
||||
messageId,
|
||||
}: {
|
||||
sessionId: string;
|
||||
messageId?: string;
|
||||
}) {
|
||||
chatTextStream(
|
||||
{
|
||||
sessionId,
|
||||
messageId,
|
||||
}: {
|
||||
sessionId: string;
|
||||
messageId?: string;
|
||||
},
|
||||
endpoint = 'stream'
|
||||
) {
|
||||
const url = new URL(
|
||||
`${this.backendUrl}/api/copilot/chat/${sessionId}/stream`
|
||||
`${this.backendUrl}/api/copilot/chat/${sessionId}/${endpoint}`
|
||||
);
|
||||
if (messageId) url.searchParams.set('messageId', messageId);
|
||||
return new EventSource(url.toString());
|
||||
|
||||
@@ -28,20 +28,20 @@ export const promptKeys = [
|
||||
'Write outline',
|
||||
'Change tone to',
|
||||
'Brainstorm ideas about this',
|
||||
'Brainstorm mindmap',
|
||||
'Expand mind map',
|
||||
'Improve writing for it',
|
||||
'Improve grammar for it',
|
||||
'Fix spelling for it',
|
||||
'Find action items from it',
|
||||
'Check code error',
|
||||
'Create a presentation',
|
||||
'Create headings',
|
||||
'Make it real',
|
||||
'Make it real with text',
|
||||
'Make it longer',
|
||||
'Make it shorter',
|
||||
'Continue writing',
|
||||
'workflow:presentation',
|
||||
'workflow:brainstorm',
|
||||
] as const;
|
||||
|
||||
export type PromptKey = (typeof promptKeys)[number];
|
||||
|
||||
@@ -22,6 +22,8 @@ export type TextToTextOptions = {
|
||||
stream?: boolean;
|
||||
signal?: AbortSignal;
|
||||
retry?: boolean;
|
||||
workflow?: boolean;
|
||||
postfix?: (text: string) => string;
|
||||
};
|
||||
|
||||
export type ToImageOptions = TextToTextOptions & {
|
||||
@@ -111,6 +113,8 @@ export function textToText({
|
||||
signal,
|
||||
timeout = TIMEOUT,
|
||||
retry = false,
|
||||
workflow = false,
|
||||
postfix,
|
||||
}: TextToTextOptions) {
|
||||
let _sessionId: string;
|
||||
let _messageId: string | undefined;
|
||||
@@ -139,10 +143,13 @@ export function textToText({
|
||||
_messageId = message.messageId;
|
||||
}
|
||||
|
||||
const eventSource = client.chatTextStream({
|
||||
sessionId: _sessionId,
|
||||
messageId: _messageId,
|
||||
});
|
||||
const eventSource = client.chatTextStream(
|
||||
{
|
||||
sessionId: _sessionId,
|
||||
messageId: _messageId,
|
||||
},
|
||||
workflow ? 'workflow' : undefined
|
||||
);
|
||||
AIProvider.LAST_ACTION_SESSIONID = _sessionId;
|
||||
|
||||
if (signal) {
|
||||
@@ -154,12 +161,25 @@ export function textToText({
|
||||
eventSource.close();
|
||||
};
|
||||
}
|
||||
for await (const event of toTextStream(eventSource, {
|
||||
timeout,
|
||||
signal,
|
||||
})) {
|
||||
if (event.type === 'message') {
|
||||
yield event.data;
|
||||
if (postfix) {
|
||||
const messages: string[] = [];
|
||||
for await (const event of toTextStream(eventSource, {
|
||||
timeout,
|
||||
signal,
|
||||
})) {
|
||||
if (event.type === 'message') {
|
||||
messages.push(event.data);
|
||||
}
|
||||
}
|
||||
yield postfix(messages.join(''));
|
||||
} else {
|
||||
for await (const event of toTextStream(eventSource, {
|
||||
timeout,
|
||||
signal,
|
||||
})) {
|
||||
if (event.type === 'message') {
|
||||
yield event.data;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -8,6 +8,7 @@ import { Trans } from '@affine/i18n';
|
||||
import { UnauthorizedError } from '@blocksuite/blocks';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import { getCurrentStore } from '@toeverything/infra';
|
||||
import { z } from 'zod';
|
||||
|
||||
import type { PromptKey } from './prompt';
|
||||
import {
|
||||
@@ -233,7 +234,8 @@ function setupAIProvider() {
|
||||
return textToText({
|
||||
...options,
|
||||
content: options.input,
|
||||
promptName: 'Brainstorm mindmap',
|
||||
promptName: 'workflow:brainstorm',
|
||||
workflow: true,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -289,10 +291,48 @@ Could you make a new website based on these notes and send back just the html fi
|
||||
});
|
||||
|
||||
AIProvider.provide('createSlides', options => {
|
||||
const SlideSchema = z.object({
|
||||
page: z.number(),
|
||||
type: z.enum(['name', 'title', 'content']),
|
||||
content: z.string(),
|
||||
});
|
||||
type Slide = z.infer<typeof SlideSchema>;
|
||||
const parseJson = (json: string) => {
|
||||
try {
|
||||
return SlideSchema.parse(JSON.parse(json));
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
// TODO(@darkskygit): move this to backend's workflow after workflow support custom code action
|
||||
const postfix = (text: string): string => {
|
||||
const slides = text
|
||||
.split('\n')
|
||||
.map(parseJson)
|
||||
.filter((v): v is Slide => !!v);
|
||||
return slides
|
||||
.map(slide => {
|
||||
if (slide.type === 'name') {
|
||||
return `- ${slide.content}`;
|
||||
} else if (slide.type === 'title') {
|
||||
return ` - ${slide.content}`;
|
||||
} else if (slide.content.includes('\n')) {
|
||||
return slide.content
|
||||
.split('\n')
|
||||
.map(c => ` - ${c}`)
|
||||
.join('\n');
|
||||
} else {
|
||||
return ` - ${slide.content}`;
|
||||
}
|
||||
})
|
||||
.join('\n');
|
||||
};
|
||||
return textToText({
|
||||
...options,
|
||||
content: options.input,
|
||||
promptName: 'Create a presentation',
|
||||
promptName: 'workflow:presentation',
|
||||
workflow: true,
|
||||
postfix,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user