mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 21:27:20 +00:00
@@ -30,10 +30,12 @@ import {
|
||||
import { CurrentUser, Public } from '../../core/auth';
|
||||
import {
|
||||
BlobNotFound,
|
||||
CallMetric,
|
||||
Config,
|
||||
CopilotFailedToGenerateText,
|
||||
CopilotSessionNotFound,
|
||||
mapSseError,
|
||||
metrics,
|
||||
NoCopilotProviderAvailable,
|
||||
UnsplashIsNotConfigured,
|
||||
} from '../../fundamentals';
|
||||
@@ -178,6 +180,7 @@ export class CopilotController {
|
||||
}
|
||||
|
||||
@Get('/chat/:sessionId')
|
||||
@CallMetric('ai', 'chat', { timer: true })
|
||||
async chat(
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@Req() req: Request,
|
||||
@@ -185,6 +188,7 @@ export class CopilotController {
|
||||
@Query() params: Record<string, string | string[]>
|
||||
): Promise<string> {
|
||||
const { messageId } = this.prepareParams(params);
|
||||
|
||||
const provider = await this.chooseTextProvider(
|
||||
user.id,
|
||||
sessionId,
|
||||
@@ -192,8 +196,8 @@ export class CopilotController {
|
||||
);
|
||||
|
||||
const session = await this.appendSessionMessage(sessionId, messageId);
|
||||
|
||||
try {
|
||||
metrics.ai.counter('chat_calls').add(1, { model: session.model });
|
||||
const content = await provider.generateText(
|
||||
session.finish(params),
|
||||
session.model,
|
||||
@@ -213,27 +217,30 @@ export class CopilotController {
|
||||
|
||||
return content;
|
||||
} catch (e: any) {
|
||||
metrics.ai.counter('chat_errors').add(1, { model: session.model });
|
||||
throw new CopilotFailedToGenerateText(e.message);
|
||||
}
|
||||
}
|
||||
|
||||
@Sse('/chat/:sessionId/stream')
|
||||
@CallMetric('ai', 'chat_stream', { timer: true })
|
||||
async chatStream(
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@Req() req: Request,
|
||||
@Param('sessionId') sessionId: string,
|
||||
@Query() params: Record<string, string>
|
||||
): Promise<Observable<ChatEvent>> {
|
||||
const { messageId } = this.prepareParams(params);
|
||||
|
||||
const provider = await this.chooseTextProvider(
|
||||
user.id,
|
||||
sessionId,
|
||||
messageId
|
||||
);
|
||||
|
||||
const session = await this.appendSessionMessage(sessionId, messageId);
|
||||
try {
|
||||
const { messageId } = this.prepareParams(params);
|
||||
const provider = await this.chooseTextProvider(
|
||||
user.id,
|
||||
sessionId,
|
||||
messageId
|
||||
);
|
||||
|
||||
const session = await this.appendSessionMessage(sessionId, messageId);
|
||||
|
||||
metrics.ai.counter('chat_stream_calls').add(1, { model: session.model });
|
||||
const source$ = from(
|
||||
provider.generateTextStream(session.finish(params), session.model, {
|
||||
...session.config.promptConfig,
|
||||
@@ -262,25 +269,34 @@ export class CopilotController {
|
||||
)
|
||||
)
|
||||
),
|
||||
catchError(mapSseError)
|
||||
catchError(e => {
|
||||
metrics.ai
|
||||
.counter('chat_stream_errors')
|
||||
.add(1, { model: session.model });
|
||||
return mapSseError(e);
|
||||
})
|
||||
);
|
||||
|
||||
return this.mergePingStream(messageId, source$);
|
||||
} catch (err) {
|
||||
metrics.ai.counter('chat_stream_errors').add(1, { model: session.model });
|
||||
return mapSseError(err);
|
||||
}
|
||||
}
|
||||
|
||||
@Sse('/chat/:sessionId/workflow')
|
||||
@CallMetric('ai', 'chat_workflow', { timer: true })
|
||||
async chatWorkflow(
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@Req() req: Request,
|
||||
@Param('sessionId') sessionId: string,
|
||||
@Query() params: Record<string, string>
|
||||
): Promise<Observable<ChatEvent>> {
|
||||
const { messageId } = this.prepareParams(params);
|
||||
|
||||
const session = await this.appendSessionMessage(sessionId, messageId);
|
||||
try {
|
||||
const { messageId } = this.prepareParams(params);
|
||||
const session = await this.appendSessionMessage(sessionId, messageId);
|
||||
metrics.ai.counter('workflow_calls').add(1, { model: session.model });
|
||||
const latestMessage = session.stashMessages.findLast(
|
||||
m => m.role === 'user'
|
||||
);
|
||||
@@ -347,41 +363,51 @@ export class CopilotController {
|
||||
)
|
||||
)
|
||||
),
|
||||
catchError(mapSseError)
|
||||
catchError(e => {
|
||||
metrics.ai
|
||||
.counter('workflow_errors')
|
||||
.add(1, { model: session.model });
|
||||
return mapSseError(e);
|
||||
})
|
||||
);
|
||||
|
||||
return this.mergePingStream(messageId, source$);
|
||||
} catch (err) {
|
||||
metrics.ai.counter('workflow_errors').add(1, { model: session.model });
|
||||
return mapSseError(err);
|
||||
}
|
||||
}
|
||||
|
||||
@Sse('/chat/:sessionId/images')
|
||||
@CallMetric('ai', 'chat_images', { timer: true })
|
||||
async chatImagesStream(
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@Req() req: Request,
|
||||
@Param('sessionId') sessionId: string,
|
||||
@Query() params: Record<string, string>
|
||||
): Promise<Observable<ChatEvent>> {
|
||||
const { messageId } = this.prepareParams(params);
|
||||
|
||||
const { model, hasAttachment } = await this.checkRequest(
|
||||
user.id,
|
||||
sessionId,
|
||||
messageId
|
||||
);
|
||||
const provider = await this.provider.getProviderByCapability(
|
||||
hasAttachment
|
||||
? CopilotCapability.ImageToImage
|
||||
: CopilotCapability.TextToImage,
|
||||
model
|
||||
);
|
||||
if (!provider) {
|
||||
throw new NoCopilotProviderAvailable();
|
||||
}
|
||||
|
||||
const session = await this.appendSessionMessage(sessionId, messageId);
|
||||
try {
|
||||
const { messageId } = this.prepareParams(params);
|
||||
const { model, hasAttachment } = await this.checkRequest(
|
||||
user.id,
|
||||
sessionId,
|
||||
messageId
|
||||
);
|
||||
const provider = await this.provider.getProviderByCapability(
|
||||
hasAttachment
|
||||
? CopilotCapability.ImageToImage
|
||||
: CopilotCapability.TextToImage,
|
||||
model
|
||||
);
|
||||
if (!provider) {
|
||||
throw new NoCopilotProviderAvailable();
|
||||
}
|
||||
|
||||
const session = await this.appendSessionMessage(sessionId, messageId);
|
||||
|
||||
metrics.ai
|
||||
.counter('images_stream_calls')
|
||||
.add(1, { model: session.model });
|
||||
const handleRemoteLink = this.storage.handleRemoteLink.bind(
|
||||
this.storage,
|
||||
user.id,
|
||||
@@ -423,15 +449,24 @@ export class CopilotController {
|
||||
)
|
||||
)
|
||||
),
|
||||
catchError(mapSseError)
|
||||
catchError(e => {
|
||||
metrics.ai
|
||||
.counter('images_stream_errors')
|
||||
.add(1, { model: session.model });
|
||||
return mapSseError(e);
|
||||
})
|
||||
);
|
||||
|
||||
return this.mergePingStream(messageId, source$);
|
||||
} catch (err) {
|
||||
metrics.ai
|
||||
.counter('images_stream_errors')
|
||||
.add(1, { model: session.model });
|
||||
return mapSseError(err);
|
||||
}
|
||||
}
|
||||
|
||||
@CallMetric('ai', 'unsplash')
|
||||
@Get('/unsplash/photos')
|
||||
async unsplashPhotos(
|
||||
@Req() req: Request,
|
||||
|
||||
Reference in New Issue
Block a user