feat(server): paginated list endpoint (#13026)

fix AI-323
This commit is contained in:
DarkSky
2025-07-08 17:11:58 +08:00
committed by GitHub
parent 8c49a45162
commit 6dac94d90a
36 changed files with 1136 additions and 702 deletions
@@ -1891,7 +1891,7 @@ test('should handle generateSessionTitle correctly under various conditions', as
await session.generateSessionTitle({ sessionId }); await session.generateSessionTitle({ sessionId });
if (testCase.expectSnapshot) { if (testCase.expectSnapshot) {
const sessionState = await session.getSession(sessionId); const sessionState = await session.getSessionInfo(sessionId);
t.snapshot( t.snapshot(
{ {
chatWithPromptCalled: testCase.expectNotCalled chatWithPromptCalled: testCase.expectNotCalled
@@ -265,26 +265,31 @@ export class CopilotSessionModel extends BaseModel {
userId: true, userId: true,
workspaceId: true, workspaceId: true,
docId: true, docId: true,
pinned: true,
parentSessionId: true, parentSessionId: true,
pinned: true,
title: true, title: true,
promptName: true,
tokenCost: true,
createdAt: true,
updatedAt: true,
messages: { messages: {
select: { select: {
id: true, id: true,
role: true, role: true,
content: true, content: true,
streamObjects: true,
attachments: true, attachments: true,
streamObjects: true,
params: true, params: true,
createdAt: true, createdAt: true,
}, },
orderBy: { createdAt: 'asc' }, orderBy: { createdAt: 'asc' },
}, },
promptName: true,
}); });
} }
async list(options: ListSessionOptions) { private getListConditions(
options: ListSessionOptions
): Prisma.AiSessionWhereInput {
const { userId, sessionId, workspaceId, docId, action, fork } = options; const { userId, sessionId, workspaceId, docId, action, fork } = options;
function getNullCond<T>( function getNullCond<T>(
@@ -330,8 +335,18 @@ export class CopilotSessionModel extends BaseModel {
}); });
} }
return { OR: conditions };
}
async count(options: ListSessionOptions) {
return await this.db.aiSession.count({
where: this.getListConditions(options),
});
}
async list(options: ListSessionOptions) {
return await this.db.aiSession.findMany({ return await this.db.aiSession.findMany({
where: { OR: conditions }, where: this.getListConditions(options),
select: { select: {
id: true, id: true,
userId: true, userId: true,
@@ -351,8 +366,8 @@ export class CopilotSessionModel extends BaseModel {
role: true, role: true,
content: true, content: true,
attachments: true, attachments: true,
params: true,
streamObjects: true, streamObjects: true,
params: true,
createdAt: true, createdAt: true,
}, },
orderBy: { orderBy: {
@@ -25,6 +25,9 @@ import {
CopilotFailedToCreateMessage, CopilotFailedToCreateMessage,
CopilotSessionNotFound, CopilotSessionNotFound,
type FileUpload, type FileUpload,
paginate,
Paginated,
PaginationInput,
RequestMutex, RequestMutex,
Throttle, Throttle,
TooManyRequest, TooManyRequest,
@@ -38,12 +41,7 @@ import { PromptService } from './prompt';
import { PromptMessage, StreamObject } from './providers'; import { PromptMessage, StreamObject } from './providers';
import { ChatSessionService } from './session'; import { ChatSessionService } from './session';
import { CopilotStorage } from './storage'; import { CopilotStorage } from './storage';
import { import { type ChatHistory, type ChatMessage, SubmittedMessage } from './types';
type ChatHistory,
type ChatMessage,
type ChatSessionState,
SubmittedMessage,
} from './types';
export const COPILOT_LOCKER = 'copilot'; export const COPILOT_LOCKER = 'copilot';
@@ -186,6 +184,9 @@ class QueryChatHistoriesInput
@Field(() => String, { nullable: true }) @Field(() => String, { nullable: true })
sessionId: string | undefined; sessionId: string | undefined;
@Field(() => Boolean, { nullable: true })
withMessages: boolean | undefined;
@Field(() => Boolean, { nullable: true }) @Field(() => Boolean, { nullable: true })
withPrompt: boolean | undefined; withPrompt: boolean | undefined;
} }
@@ -239,7 +240,7 @@ class ChatMessageType implements Partial<ChatMessage> {
} }
@ObjectType('CopilotHistories') @ObjectType('CopilotHistories')
class CopilotHistoriesType implements Partial<ChatHistory> { class CopilotHistoriesType implements Omit<ChatHistory, 'userId'> {
@Field(() => String) @Field(() => String)
sessionId!: string; sessionId!: string;
@@ -249,8 +250,17 @@ class CopilotHistoriesType implements Partial<ChatHistory> {
@Field(() => String, { nullable: true }) @Field(() => String, { nullable: true })
docId!: string | null; docId!: string | null;
@Field(() => Boolean) @Field(() => String, { nullable: true })
pinned!: boolean; parentSessionId!: string | null;
@Field(() => String)
promptName!: string;
@Field(() => String)
model!: string;
@Field(() => [String])
optionalModels!: string[];
@Field(() => String, { @Field(() => String, {
description: 'An mark identifying which view to use to display the session', description: 'An mark identifying which view to use to display the session',
@@ -258,6 +268,12 @@ class CopilotHistoriesType implements Partial<ChatHistory> {
}) })
action!: string | null; action!: string | null;
@Field(() => Boolean)
pinned!: boolean;
@Field(() => String, { nullable: true })
title!: string | null;
@Field(() => Number, { @Field(() => Number, {
description: 'The number of tokens used in the session', description: 'The number of tokens used in the session',
}) })
@@ -273,6 +289,11 @@ class CopilotHistoriesType implements Partial<ChatHistory> {
updatedAt!: Date; updatedAt!: Date;
} }
@ObjectType()
export class PaginatedCopilotHistoriesType extends Paginated(
CopilotHistoriesType
) {}
@ObjectType('CopilotQuota') @ObjectType('CopilotQuota')
class CopilotQuotaType { class CopilotQuotaType {
@Field(() => SafeIntResolver, { nullable: true }) @Field(() => SafeIntResolver, { nullable: true })
@@ -421,7 +442,7 @@ export class CopilotResolver {
@Args('sessionId') sessionId: string @Args('sessionId') sessionId: string
): Promise<CopilotSessionType> { ): Promise<CopilotSessionType> {
await this.assertPermission(user, copilot); await this.assertPermission(user, copilot);
const session = await this.chatSession.getSession(sessionId); const session = await this.chatSession.getSessionInfo(sessionId);
if (!session) { if (!session) {
throw new NotFoundException('Session not found'); throw new NotFoundException('Session not found');
} }
@@ -430,6 +451,7 @@ export class CopilotResolver {
@ResolveField(() => [CopilotSessionType], { @ResolveField(() => [CopilotSessionType], {
description: 'Get the session list in the workspace', description: 'Get the session list in the workspace',
deprecationReason: 'use `chats` instead',
complexity: 2, complexity: 2,
}) })
async sessions( async sessions(
@@ -447,11 +469,12 @@ export class CopilotResolver {
Object.assign({}, copilot, { docId: maybeDocId }) Object.assign({}, copilot, { docId: maybeDocId })
); );
const sessions = await this.chatSession.listSessions( const sessions = await this.chatSession.list(
Object.assign({}, options, appendOptions) Object.assign({}, options, appendOptions),
false
); );
if (appendOptions.docId) { if (appendOptions.docId) {
type Session = Omit<ChatSessionState, 'messages'> & { docId: string }; type Session = ChatHistory & { docId: string };
const filtered = sessions.filter((s): s is Session => !!s.docId); const filtered = sessions.filter((s): s is Session => !!s.docId);
const accessible = await this.ac const accessible = await this.ac
.user(user.id) .user(user.id)
@@ -463,7 +486,9 @@ export class CopilotResolver {
} }
} }
@ResolveField(() => [CopilotHistoriesType], {}) @ResolveField(() => [CopilotHistoriesType], {
deprecationReason: 'use `chats` instead',
})
@CallMetric('ai', 'histories') @CallMetric('ai', 'histories')
async histories( async histories(
@Parent() copilot: CopilotType, @Parent() copilot: CopilotType,
@@ -478,8 +503,9 @@ export class CopilotResolver {
await this.assertPermission(user, { workspaceId, docId }); await this.assertPermission(user, { workspaceId, docId });
} }
const histories = await this.chatSession.listHistories( const histories = await this.chatSession.list(
Object.assign({}, options, { userId: user.id, workspaceId, docId }) Object.assign({}, options, { userId: user.id, workspaceId, docId }),
true
); );
return histories.map(h => ({ return histories.map(h => ({
@@ -491,6 +517,48 @@ export class CopilotResolver {
})); }));
} }
@ResolveField(() => PaginatedCopilotHistoriesType, {})
@CallMetric('ai', 'histories')
async chats(
@Parent() copilot: CopilotType,
@CurrentUser() user: CurrentUser,
@Args('pagination', PaginationInput.decode) pagination: PaginationInput,
@Args('docId', { nullable: true }) docId?: string,
@Args('options', { nullable: true }) options?: QueryChatHistoriesInput
): Promise<PaginatedCopilotHistoriesType> {
const workspaceId = copilot.workspaceId;
if (!workspaceId) {
return paginate([], 'updatedAt', pagination, 0);
} else {
await this.assertPermission(user, { workspaceId, docId });
}
const finalOptions = Object.assign(
{},
options,
{ userId: user.id, workspaceId, docId },
{ skip: pagination.offset, limit: pagination.first }
);
const totalCount = await this.chatSession.count(finalOptions);
const histories = await this.chatSession.list(
finalOptions,
!!options?.withMessages
);
return paginate(
histories.map(h => ({
...h,
// filter out empty messages
messages: h.messages?.filter(
m => m.content || m.attachments?.length
) as ChatMessageType[],
})),
'updatedAt',
pagination,
totalCount
);
}
@Mutation(() => String, { @Mutation(() => String, {
description: 'Create a chat session', description: 'Create a chat session',
}) })
@@ -657,18 +725,9 @@ export class CopilotResolver {
} }
private transformToSessionType( private transformToSessionType(
session: Omit<ChatSessionState, 'messages'> session: Omit<ChatHistory, 'messages'>
): CopilotSessionType { ): CopilotSessionType {
return { return { id: session.sessionId, ...session };
id: session.sessionId,
parentSessionId: session.parentSessionId,
docId: session.docId,
pinned: session.pinned,
title: session.title,
promptName: session.prompt.name,
model: session.prompt.model,
optionalModels: session.prompt.optionalModels,
};
} }
} }
@@ -4,6 +4,7 @@ import { Injectable, Logger } from '@nestjs/common';
import { ModuleRef } from '@nestjs/core'; import { ModuleRef } from '@nestjs/core';
import { Transactional } from '@nestjs-cls/transactional'; import { Transactional } from '@nestjs-cls/transactional';
import { AiPromptRole } from '@prisma/client'; import { AiPromptRole } from '@prisma/client';
import { pick } from 'lodash-es';
import { import {
CopilotActionTaken, CopilotActionTaken,
@@ -25,7 +26,7 @@ import {
UpdateChatSessionOptions, UpdateChatSessionOptions,
} from '../../models'; } from '../../models';
import { ChatMessageCache } from './message'; import { ChatMessageCache } from './message';
import { PromptService } from './prompt'; import { ChatPrompt, PromptService } from './prompt';
import { import {
CopilotProviderFactory, CopilotProviderFactory,
ModelOutputType, ModelOutputType,
@@ -240,6 +241,14 @@ export class ChatSession implements AsyncDisposable {
} }
} }
type Session = NonNullable<
Awaited<ReturnType<Models['copilotSession']['get']>>
>;
type SessionHistory = ChatHistory & {
prompt: ChatPrompt;
};
@Injectable() @Injectable()
export class ChatSessionService { export class ChatSessionService {
private readonly logger = new Logger(ChatSessionService.name); private readonly logger = new Logger(ChatSessionService.name);
@@ -253,27 +262,55 @@ export class ChatSessionService {
private readonly prompt: PromptService private readonly prompt: PromptService
) {} ) {}
async getSession(sessionId: string): Promise<ChatSessionState | undefined> { private getMessage(session: Session): ChatMessage[] {
const session = await this.models.copilotSession.get(sessionId); if (!Array.isArray(session.messages) || !session.messages.length) {
if (!session) return; return [];
}
const messages = ChatMessageSchema.array().safeParse(session.messages);
if (!messages.success) {
this.logger.error(
`Unexpected message schema: ${JSON.stringify(messages.error)}`
);
return [];
}
return messages.data;
}
private async getHistory(session: Session): Promise<SessionHistory> {
const prompt = await this.prompt.get(session.promptName); const prompt = await this.prompt.get(session.promptName);
if (!prompt) throw new CopilotPromptNotFound({ name: session.promptName }); if (!prompt) throw new CopilotPromptNotFound({ name: session.promptName });
const messages = ChatMessageSchema.array().safeParse(session.messages);
return { return {
...pick(session, [
'userId',
'workspaceId',
'docId',
'parentSessionId',
'pinned',
'title',
'createdAt',
'updatedAt',
]),
sessionId: session.id, sessionId: session.id,
userId: session.userId, tokens: session.tokenCost,
workspaceId: session.workspaceId, messages: this.getMessage(session),
docId: session.docId,
pinned: session.pinned, // prompt info
title: session.title,
parentSessionId: session.parentSessionId,
prompt, prompt,
messages: messages.success ? messages.data : [], action: prompt.action || null,
model: prompt.model,
optionalModels: prompt.optionalModels || null,
promptName: prompt.name,
}; };
} }
async getSessionInfo(sessionId: string): Promise<SessionHistory | undefined> {
const session = await this.models.copilotSession.get(sessionId);
if (!session) return;
return await this.getHistory(session);
}
// revert the latest messages not generate by user // revert the latest messages not generate by user
// after revert, we can retry the action // after revert, we can retry the action
async revertLatestMessage( async revertLatestMessage(
@@ -286,116 +323,70 @@ export class ChatSessionService {
); );
} }
async listSessions( async count(options: ListSessionOptions): Promise<number> {
options: ListSessionOptions return await this.models.copilotSession.count(options);
): Promise<Omit<ChatSessionState, 'messages'>[]> {
const sessions = await this.models.copilotSession.list({
...options,
withMessages: false,
});
return Promise.all(
sessions.map(async session => {
const prompt = await this.prompt.get(session.promptName);
if (!prompt)
throw new CopilotPromptNotFound({ name: session.promptName });
return {
sessionId: session.id,
userId: session.userId,
workspaceId: session.workspaceId,
docId: session.docId,
pinned: session.pinned,
title: session.title,
parentSessionId: session.parentSessionId,
prompt,
};
})
);
} }
async listHistories(options: ListSessionOptions): Promise<ChatHistory[]> { async list(
const { userId } = options; options: ListSessionOptions,
withMessages: boolean
): Promise<ChatHistory[]> {
const { userId: reqUserId } = options;
const sessions = await this.models.copilotSession.list({ const sessions = await this.models.copilotSession.list({
...options, ...options,
withMessages: true, withMessages,
}); });
const histories = await Promise.all( const histories = await Promise.all(
sessions.map( sessions.map(async session => {
async ({ const { userId, id: sessionId, createdAt } = session;
userId: uid, try {
id, const { prompt, messages, ...baseHistory } =
workspaceId, await this.getHistory(session);
docId,
pinned, if (withMessages) {
title,
promptName,
tokenCost,
messages,
createdAt,
updatedAt,
}) => {
try {
const prompt = await this.prompt.get(promptName);
if (!prompt) {
throw new CopilotPromptNotFound({ name: promptName });
}
if ( if (
// filter out the user's session that not match the action option // filter out the user's session that not match the action option
(uid === userId && !!options?.action !== !!prompt.action) || (userId === reqUserId && !!options?.action !== !!prompt.action) ||
// filter out the non chat session from other user // filter out the non chat session from other user
(uid !== userId && !!prompt.action) (userId !== reqUserId && !!prompt.action)
) { ) {
return undefined; return undefined;
} }
const ret = ChatMessageSchema.array().safeParse(messages); // render system prompt
if (ret.success) { const preload = (
// render system prompt options?.withPrompt
const preload = ( ? prompt
options?.withPrompt .finish(messages[0]?.params || {}, sessionId)
? prompt .filter(({ role }) => role !== 'system')
.finish(ret.data[0]?.params || {}, id) : []
.filter(({ role }) => role !== 'system') ) as ChatMessage[];
: []
) as ChatMessage[];
// `createdAt` is required for history sorting in frontend // `createdAt` is required for history sorting in frontend
// let's fake the creating time of prompt messages // let's fake the creating time of prompt messages
preload.forEach((msg, i) => { preload.forEach((msg, i) => {
msg.createdAt = new Date( msg.createdAt = new Date(
createdAt.getTime() - preload.length - i - 1 createdAt.getTime() - preload.length - i - 1
);
});
return {
sessionId: id,
workspaceId,
docId,
pinned,
title,
action: prompt.action || null,
tokens: tokenCost,
createdAt,
updatedAt,
messages: preload.concat(ret.data).map(m => ({
...m,
attachments: m.attachments
?.map(a => (typeof a === 'string' ? a : a.attachment))
.filter(a => !!a),
})),
};
} else {
this.logger.error(
`Unexpected message schema: ${JSON.stringify(ret.error)}`
); );
} });
} catch (e) {
this.logger.error('Unexpected error in listHistories', e); return {
...baseHistory,
messages: preload.concat(messages).map(m => ({
...m,
attachments: m.attachments
?.map(a => (typeof a === 'string' ? a : a.attachment))
.filter(a => !!a),
})),
};
} else {
return { ...baseHistory, messages: [] };
} }
return undefined; } catch (e) {
this.logger.error('Unexpected error in list ChatHistories', e);
} }
) return undefined;
})
); );
return histories.filter((v): v is NonNullable<typeof v> => !!v); return histories.filter((v): v is NonNullable<typeof v> => !!v);
@@ -461,7 +452,7 @@ export class ChatSessionService {
@Transactional() @Transactional()
async update(options: UpdateChatSession): Promise<string> { async update(options: UpdateChatSession): Promise<string> {
const session = await this.getSession(options.sessionId); const session = await this.getSessionInfo(options.sessionId);
if (!session) { if (!session) {
throw new CopilotSessionNotFound(); throw new CopilotSessionNotFound();
} }
@@ -494,14 +485,14 @@ export class ChatSessionService {
@Transactional() @Transactional()
async fork(options: ChatSessionForkOptions): Promise<string> { async fork(options: ChatSessionForkOptions): Promise<string> {
const state = await this.getSession(options.sessionId); const session = await this.getSessionInfo(options.sessionId);
if (!state) { if (!session) {
throw new CopilotSessionNotFound(); throw new CopilotSessionNotFound();
} }
let messages = state.messages.map(m => ({ ...m, id: undefined })); let messages = session.messages.map(m => ({ ...m, id: undefined }));
if (options.latestMessageId) { if (options.latestMessageId) {
const lastMessageIdx = state.messages.findLastIndex( const lastMessageIdx = session.messages.findLastIndex(
({ id, role }) => ({ id, role }) =>
role === AiPromptRole.assistant && id === options.latestMessageId role === AiPromptRole.assistant && id === options.latestMessageId
); );
@@ -514,7 +505,7 @@ export class ChatSessionService {
} }
return await this.models.copilotSession.fork({ return await this.models.copilotSession.fork({
...state, ...session,
userId: options.userId, userId: options.userId,
sessionId: randomUUID(), sessionId: randomUUID(),
parentSessionId: options.sessionId, parentSessionId: options.sessionId,
@@ -544,7 +535,7 @@ export class ChatSessionService {
* @returns * @returns
*/ */
async get(sessionId: string): Promise<ChatSession | null> { async get(sessionId: string): Promise<ChatSession | null> {
const state = await this.getSession(sessionId); const state = await this.getSessionInfo(sessionId);
if (state) { if (state) {
return new ChatSession(this.messageCache, state, async state => { return new ChatSession(this.messageCache, state, async state => {
await this.models.copilotSession.updateMessages(state); await this.models.copilotSession.updateMessages(state);
@@ -46,12 +46,19 @@ export type ChatMessage = z.infer<typeof ChatMessageSchema>;
export const ChatHistorySchema = z export const ChatHistorySchema = z
.object({ .object({
userId: z.string(),
sessionId: z.string(), sessionId: z.string(),
workspaceId: z.string(), workspaceId: z.string(),
docId: z.string().nullable(), docId: z.string().nullable(),
parentSessionId: z.string().nullable(),
pinned: z.boolean(), pinned: z.boolean(),
title: z.string().nullable(), title: z.string().nullable(),
action: z.string().nullable(), action: z.string().nullable(),
model: z.string(),
optionalModels: z.array(z.string()),
promptName: z.string(),
tokens: z.number(), tokens: z.number(),
messages: z.array(ChatMessageSchema), messages: z.array(ChatMessageSchema),
createdAt: z.date(), createdAt: z.date(),
@@ -69,32 +76,26 @@ export type SubmittedMessage = z.infer<typeof SubmittedMessageSchema>;
// ======== Chat Session ======== // ======== Chat Session ========
export interface ChatSessionOptions { export type ChatSessionOptions = Pick<
// connect ids ChatHistory,
userId: string; 'userId' | 'workspaceId' | 'docId' | 'promptName' | 'pinned'
workspaceId: string; > & {
docId: string | null;
promptName: string;
pinned: boolean;
reuseLatestChat?: boolean; reuseLatestChat?: boolean;
} };
export interface ChatSessionForkOptions export type ChatSessionForkOptions = Pick<
extends Omit<ChatSessionOptions, 'pinned' | 'promptName'> { ChatHistory,
sessionId: string; 'userId' | 'sessionId' | 'workspaceId' | 'docId'
> & {
latestMessageId?: string; latestMessageId?: string;
} };
export interface ChatSessionState export type ChatSessionState = Pick<
extends Omit<ChatSessionOptions, 'promptName'> { ChatHistory,
title: string | null; 'userId' | 'sessionId' | 'workspaceId' | 'docId' | 'messages'
// connect ids > & {
sessionId: string;
parentSessionId: string | null;
// states
prompt: ChatPrompt; prompt: ChatPrompt;
messages: ChatMessage[]; };
}
export type CopilotContextFile = { export type CopilotContextFile = {
id: string; // fileId id: string; // fileId
+20 -2
View File
@@ -208,10 +208,11 @@ type ContextWorkspaceEmbeddingStatus {
type Copilot { type Copilot {
audioTranscription(blobId: String, jobId: String): TranscriptionResultType audioTranscription(blobId: String, jobId: String): TranscriptionResultType
chats(docId: String, options: QueryChatHistoriesInput, pagination: PaginationInput!): PaginatedCopilotHistoriesType!
"""Get the context list of a session""" """Get the context list of a session"""
contexts(contextId: String, sessionId: String): [CopilotContext!]! contexts(contextId: String, sessionId: String): [CopilotContext!]!
histories(docId: String, options: QueryChatHistoriesInput): [CopilotHistories!]! histories(docId: String, options: QueryChatHistoriesInput): [CopilotHistories!]! @deprecated(reason: "use `chats` instead")
"""Get the quota of the user in the workspace""" """Get the quota of the user in the workspace"""
quota: CopilotQuota! quota: CopilotQuota!
@@ -220,7 +221,7 @@ type Copilot {
session(sessionId: String!): CopilotSessionType! session(sessionId: String!): CopilotSessionType!
"""Get the session list in the workspace""" """Get the session list in the workspace"""
sessions(docId: String, options: QueryChatSessionsInput): [CopilotSessionType!]! sessions(docId: String, options: QueryChatSessionsInput): [CopilotSessionType!]! @deprecated(reason: "use `chats` instead")
workspaceId: ID workspaceId: ID
} }
@@ -313,8 +314,13 @@ type CopilotHistories {
createdAt: DateTime! createdAt: DateTime!
docId: String docId: String
messages: [ChatMessage!]! messages: [ChatMessage!]!
model: String!
optionalModels: [String!]!
parentSessionId: String
pinned: Boolean! pinned: Boolean!
promptName: String!
sessionId: String! sessionId: String!
title: String
"""The number of tokens used in the session""" """The number of tokens used in the session"""
tokens: Int! tokens: Int!
@@ -322,6 +328,11 @@ type CopilotHistories {
workspaceId: String! workspaceId: String!
} }
type CopilotHistoriesTypeEdge {
cursor: String!
node: CopilotHistories!
}
type CopilotInvalidContextDataType { type CopilotInvalidContextDataType {
contextId: String! contextId: String!
} }
@@ -1421,6 +1432,12 @@ type PaginatedCommentObjectType {
totalCount: Int! totalCount: Int!
} }
type PaginatedCopilotHistoriesType {
edges: [CopilotHistoriesTypeEdge!]!
pageInfo: PageInfo!
totalCount: Int!
}
type PaginatedCopilotWorkspaceFileType { type PaginatedCopilotWorkspaceFileType {
edges: [CopilotWorkspaceFileTypeEdge!]! edges: [CopilotWorkspaceFileTypeEdge!]!
pageInfo: PageInfo! pageInfo: PageInfo!
@@ -1552,6 +1569,7 @@ input QueryChatHistoriesInput {
sessionId: String sessionId: String
sessionOrder: ChatHistoryOrder sessionOrder: ChatHistoryOrder
skip: Int skip: Int
withMessages: Boolean
withPrompt: Boolean withPrompt: Boolean
} }
@@ -1,17 +1,29 @@
query getCopilotHistoryIds( query getCopilotHistoryIds(
$workspaceId: String! $workspaceId: String!
$pagination: PaginationInput!
$docId: String $docId: String
$options: QueryChatHistoriesInput $options: QueryChatHistoriesInput
) { ) {
currentUser { currentUser {
copilot(workspaceId: $workspaceId) { copilot(workspaceId: $workspaceId) {
histories(docId: $docId, options: $options) { chats(pagination: $pagination, docId: $docId, options: $options) {
sessionId pageInfo {
pinned hasNextPage
messages { hasPreviousPage
id startCursor
role endCursor
createdAt }
edges {
cursor
node {
sessionId
pinned
messages {
id
role
createdAt
}
}
} }
} }
} }
@@ -1,31 +1,15 @@
#import "./fragments/copilot.gql"
query getCopilotDocSessions( query getCopilotDocSessions(
$workspaceId: String! $workspaceId: String!
$docId: String! $docId: String!
$pagination: PaginationInput!
$options: QueryChatHistoriesInput $options: QueryChatHistoriesInput
) { ) {
currentUser { currentUser {
copilot(workspaceId: $workspaceId) { copilot(workspaceId: $workspaceId) {
histories(docId: $docId, options: $options) { chats(pagination: $pagination, docId: $docId, options: $options) {
sessionId ...PaginatedCopilotChats
pinned
tokens
action
createdAt
messages {
id
role
content
streamObjects {
type
textDelta
toolCallId
toolName
args
result
}
attachments
createdAt
}
} }
} }
} }
@@ -1,3 +1,5 @@
#import "./fragments/copilot.gql"
query getCopilotPinnedSessions( query getCopilotPinnedSessions(
$workspaceId: String! $workspaceId: String!
$docId: String $docId: String
@@ -6,32 +8,12 @@ query getCopilotPinnedSessions(
) { ) {
currentUser { currentUser {
copilot(workspaceId: $workspaceId) { copilot(workspaceId: $workspaceId) {
histories(docId: $docId, options: { chats(pagination: { first: 1 }, docId: $docId, options: {
limit: 1,
pinned: true, pinned: true,
messageOrder: $messageOrder, messageOrder: $messageOrder,
withPrompt: $withPrompt withPrompt: $withPrompt
}) { }) {
sessionId ...PaginatedCopilotChats
pinned
tokens
action
createdAt
messages {
id
role
content
streamObjects {
type
textDelta
toolCallId
toolName
args
result
}
attachments
createdAt
}
} }
} }
} }
@@ -1,30 +1,14 @@
#import "./fragments/copilot.gql"
query getCopilotWorkspaceSessions( query getCopilotWorkspaceSessions(
$workspaceId: String! $workspaceId: String!
$pagination: PaginationInput!
$options: QueryChatHistoriesInput $options: QueryChatHistoriesInput
) { ) {
currentUser { currentUser {
copilot(workspaceId: $workspaceId) { copilot(workspaceId: $workspaceId) {
histories(docId: null, options: $options) { chats(pagination: $pagination, docId: null, options: $options) {
sessionId ...PaginatedCopilotChats
pinned
tokens
action
createdAt
messages {
id
role
content
streamObjects {
type
textDelta
toolCallId
toolName
args
result
}
attachments
createdAt
}
} }
} }
} }
@@ -1,31 +1,15 @@
#import "./fragments/copilot.gql"
query getCopilotHistories( query getCopilotHistories(
$workspaceId: String! $workspaceId: String!
$pagination: PaginationInput!
$docId: String $docId: String
$options: QueryChatHistoriesInput $options: QueryChatHistoriesInput
) { ) {
currentUser { currentUser {
copilot(workspaceId: $workspaceId) { copilot(workspaceId: $workspaceId) {
histories(docId: $docId, options: $options) { chats(pagination: $pagination, docId: $docId, options: $options) {
sessionId ...PaginatedCopilotChats
pinned
tokens
action
createdAt
messages {
id
role
content
streamObjects {
type
textDelta
toolCallId
toolName
args
result
}
attachments
createdAt
}
} }
} }
} }
@@ -1,34 +1,22 @@
#import "./fragments/copilot.gql"
query getCopilotLatestDocSession( query getCopilotLatestDocSession(
$workspaceId: String! $workspaceId: String!
$docId: String! $docId: String!
) { ) {
currentUser { currentUser {
copilot(workspaceId: $workspaceId) { copilot(workspaceId: $workspaceId) {
histories( chats(
pagination: { first: 1 }
docId: $docId docId: $docId
options: { options: {
limit: 1
sessionOrder: desc sessionOrder: desc
action: false action: false
fork: false fork: false
withMessages: true
} }
) { ) {
sessionId ...PaginatedCopilotChats
workspaceId
docId
pinned
action
tokens
createdAt
updatedAt
messages {
id
role
content
attachments
params
createdAt
}
} }
} }
} }
@@ -1,18 +1,16 @@
#import "./fragments/copilot.gql"
query getCopilotSession( query getCopilotSession(
$workspaceId: String! $workspaceId: String!
$sessionId: String! $sessionId: String!
) { ) {
currentUser { currentUser {
copilot(workspaceId: $workspaceId) { copilot(workspaceId: $workspaceId) {
session(sessionId: $sessionId) { chats(
id pagination: { first: 1 }
parentSessionId options: { sessionId: $sessionId }
docId ) {
pinned ...PaginatedCopilotChats
title
promptName
model
optionalModels
} }
} }
} }
@@ -1,23 +1,20 @@
#import "./fragments/copilot.gql"
query getCopilotRecentSessions( query getCopilotRecentSessions(
$workspaceId: String! $workspaceId: String!
$limit: Int = 10 $limit: Int = 10
) { ) {
currentUser { currentUser {
copilot(workspaceId: $workspaceId) { copilot(workspaceId: $workspaceId) {
histories( chats(
pagination: { first: $limit }
options: { options: {
limit: $limit fork: false
sessionOrder: desc sessionOrder: desc
withMessages: true
} }
) { ) {
sessionId ...PaginatedCopilotChats
workspaceId
docId
pinned
action
tokens
createdAt
updatedAt
} }
} }
} }
@@ -1,19 +1,15 @@
#import "./fragments/copilot.gql"
query getCopilotSessions( query getCopilotSessions(
$workspaceId: String! $workspaceId: String!
$pagination: PaginationInput!
$docId: String $docId: String
$options: QueryChatSessionsInput $options: QueryChatHistoriesInput
) { ) {
currentUser { currentUser {
copilot(workspaceId: $workspaceId) { copilot(workspaceId: $workspaceId) {
sessions(docId: $docId, options: $options) { chats(pagination: $pagination, docId: $docId, options: $options) {
id ...PaginatedCopilotChats
parentSessionId
docId
pinned
title
promptName
model
optionalModels
} }
} }
} }
@@ -0,0 +1,49 @@
fragment CopilotChatMessage on ChatMessage {
id
role
content
attachments
streamObjects {
type
textDelta
toolCallId
toolName
args
result
}
createdAt
}
fragment CopilotChatHistory on CopilotHistories {
sessionId
workspaceId
docId
parentSessionId
promptName
model
optionalModels
action
pinned
title
tokens
messages {
...CopilotChatMessage
}
createdAt
updatedAt
}
fragment PaginatedCopilotChats on PaginatedCopilotHistoriesType {
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
edges {
cursor
node {
...CopilotChatHistory
}
}
}
+125 -150
View File
@@ -6,6 +6,53 @@ export interface GraphQLQuery {
file?: boolean; file?: boolean;
deprecations?: string[]; deprecations?: string[];
} }
export const copilotChatMessageFragment = `fragment CopilotChatMessage on ChatMessage {
id
role
content
attachments
streamObjects {
type
textDelta
toolCallId
toolName
args
result
}
createdAt
}`;
export const copilotChatHistoryFragment = `fragment CopilotChatHistory on CopilotHistories {
sessionId
workspaceId
docId
parentSessionId
promptName
model
optionalModels
action
pinned
title
tokens
messages {
...CopilotChatMessage
}
createdAt
updatedAt
}`;
export const paginatedCopilotChatsFragment = `fragment PaginatedCopilotChats on PaginatedCopilotHistoriesType {
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
edges {
cursor
node {
...CopilotChatHistory
}
}
}`;
export const credentialsRequirementsFragment = `fragment CredentialsRequirements on CredentialsRequirementType { export const credentialsRequirementsFragment = `fragment CredentialsRequirements on CredentialsRequirementType {
password { password {
...PasswordLimits ...PasswordLimits
@@ -762,16 +809,27 @@ export const queueWorkspaceEmbeddingMutation = {
export const getCopilotHistoryIdsQuery = { export const getCopilotHistoryIdsQuery = {
id: 'getCopilotHistoryIdsQuery' as const, id: 'getCopilotHistoryIdsQuery' as const,
op: 'getCopilotHistoryIds', op: 'getCopilotHistoryIds',
query: `query getCopilotHistoryIds($workspaceId: String!, $docId: String, $options: QueryChatHistoriesInput) { query: `query getCopilotHistoryIds($workspaceId: String!, $pagination: PaginationInput!, $docId: String, $options: QueryChatHistoriesInput) {
currentUser { currentUser {
copilot(workspaceId: $workspaceId) { copilot(workspaceId: $workspaceId) {
histories(docId: $docId, options: $options) { chats(pagination: $pagination, docId: $docId, options: $options) {
sessionId pageInfo {
pinned hasNextPage
messages { hasPreviousPage
id startCursor
role endCursor
createdAt }
edges {
cursor
node {
sessionId
pinned
messages {
id
role
createdAt
}
}
} }
} }
} }
@@ -782,34 +840,18 @@ export const getCopilotHistoryIdsQuery = {
export const getCopilotDocSessionsQuery = { export const getCopilotDocSessionsQuery = {
id: 'getCopilotDocSessionsQuery' as const, id: 'getCopilotDocSessionsQuery' as const,
op: 'getCopilotDocSessions', op: 'getCopilotDocSessions',
query: `query getCopilotDocSessions($workspaceId: String!, $docId: String!, $options: QueryChatHistoriesInput) { query: `query getCopilotDocSessions($workspaceId: String!, $docId: String!, $pagination: PaginationInput!, $options: QueryChatHistoriesInput) {
currentUser { currentUser {
copilot(workspaceId: $workspaceId) { copilot(workspaceId: $workspaceId) {
histories(docId: $docId, options: $options) { chats(pagination: $pagination, docId: $docId, options: $options) {
sessionId ...PaginatedCopilotChats
pinned
tokens
action
createdAt
messages {
id
role
content
streamObjects {
type
textDelta
toolCallId
toolName
args
result
}
attachments
createdAt
}
} }
} }
} }
}`, }
${copilotChatMessageFragment}
${copilotChatHistoryFragment}
${paginatedCopilotChatsFragment}`,
}; };
export const getCopilotPinnedSessionsQuery = { export const getCopilotPinnedSessionsQuery = {
@@ -818,100 +860,53 @@ export const getCopilotPinnedSessionsQuery = {
query: `query getCopilotPinnedSessions($workspaceId: String!, $docId: String, $messageOrder: ChatHistoryOrder, $withPrompt: Boolean) { query: `query getCopilotPinnedSessions($workspaceId: String!, $docId: String, $messageOrder: ChatHistoryOrder, $withPrompt: Boolean) {
currentUser { currentUser {
copilot(workspaceId: $workspaceId) { copilot(workspaceId: $workspaceId) {
histories( chats(
pagination: {first: 1}
docId: $docId docId: $docId
options: {limit: 1, pinned: true, messageOrder: $messageOrder, withPrompt: $withPrompt} options: {pinned: true, messageOrder: $messageOrder, withPrompt: $withPrompt}
) { ) {
sessionId ...PaginatedCopilotChats
pinned
tokens
action
createdAt
messages {
id
role
content
streamObjects {
type
textDelta
toolCallId
toolName
args
result
}
attachments
createdAt
}
} }
} }
} }
}`, }
${copilotChatMessageFragment}
${copilotChatHistoryFragment}
${paginatedCopilotChatsFragment}`,
}; };
export const getCopilotWorkspaceSessionsQuery = { export const getCopilotWorkspaceSessionsQuery = {
id: 'getCopilotWorkspaceSessionsQuery' as const, id: 'getCopilotWorkspaceSessionsQuery' as const,
op: 'getCopilotWorkspaceSessions', op: 'getCopilotWorkspaceSessions',
query: `query getCopilotWorkspaceSessions($workspaceId: String!, $options: QueryChatHistoriesInput) { query: `query getCopilotWorkspaceSessions($workspaceId: String!, $pagination: PaginationInput!, $options: QueryChatHistoriesInput) {
currentUser { currentUser {
copilot(workspaceId: $workspaceId) { copilot(workspaceId: $workspaceId) {
histories(docId: null, options: $options) { chats(pagination: $pagination, docId: null, options: $options) {
sessionId ...PaginatedCopilotChats
pinned
tokens
action
createdAt
messages {
id
role
content
streamObjects {
type
textDelta
toolCallId
toolName
args
result
}
attachments
createdAt
}
} }
} }
} }
}`, }
${copilotChatMessageFragment}
${copilotChatHistoryFragment}
${paginatedCopilotChatsFragment}`,
}; };
export const getCopilotHistoriesQuery = { export const getCopilotHistoriesQuery = {
id: 'getCopilotHistoriesQuery' as const, id: 'getCopilotHistoriesQuery' as const,
op: 'getCopilotHistories', op: 'getCopilotHistories',
query: `query getCopilotHistories($workspaceId: String!, $docId: String, $options: QueryChatHistoriesInput) { query: `query getCopilotHistories($workspaceId: String!, $pagination: PaginationInput!, $docId: String, $options: QueryChatHistoriesInput) {
currentUser { currentUser {
copilot(workspaceId: $workspaceId) { copilot(workspaceId: $workspaceId) {
histories(docId: $docId, options: $options) { chats(pagination: $pagination, docId: $docId, options: $options) {
sessionId ...PaginatedCopilotChats
pinned
tokens
action
createdAt
messages {
id
role
content
streamObjects {
type
textDelta
toolCallId
toolName
args
result
}
attachments
createdAt
}
} }
} }
} }
}`, }
${copilotChatMessageFragment}
${copilotChatHistoryFragment}
${paginatedCopilotChatsFragment}`,
}; };
export const submitAudioTranscriptionMutation = { export const submitAudioTranscriptionMutation = {
@@ -1039,30 +1034,19 @@ export const getCopilotLatestDocSessionQuery = {
query: `query getCopilotLatestDocSession($workspaceId: String!, $docId: String!) { query: `query getCopilotLatestDocSession($workspaceId: String!, $docId: String!) {
currentUser { currentUser {
copilot(workspaceId: $workspaceId) { copilot(workspaceId: $workspaceId) {
histories( chats(
pagination: {first: 1}
docId: $docId docId: $docId
options: {limit: 1, sessionOrder: desc, action: false, fork: false} options: {sessionOrder: desc, action: false, fork: false, withMessages: true}
) { ) {
sessionId ...PaginatedCopilotChats
workspaceId
docId
pinned
action
tokens
createdAt
updatedAt
messages {
id
role
content
attachments
params
createdAt
}
} }
} }
} }
}`, }
${copilotChatMessageFragment}
${copilotChatHistoryFragment}
${paginatedCopilotChatsFragment}`,
}; };
export const getCopilotSessionQuery = { export const getCopilotSessionQuery = {
@@ -1071,19 +1055,15 @@ export const getCopilotSessionQuery = {
query: `query getCopilotSession($workspaceId: String!, $sessionId: String!) { query: `query getCopilotSession($workspaceId: String!, $sessionId: String!) {
currentUser { currentUser {
copilot(workspaceId: $workspaceId) { copilot(workspaceId: $workspaceId) {
session(sessionId: $sessionId) { chats(pagination: {first: 1}, options: {sessionId: $sessionId}) {
id ...PaginatedCopilotChats
parentSessionId
docId
pinned
title
promptName
model
optionalModels
} }
} }
} }
}`, }
${copilotChatMessageFragment}
${copilotChatHistoryFragment}
${paginatedCopilotChatsFragment}`,
}; };
export const getCopilotRecentSessionsQuery = { export const getCopilotRecentSessionsQuery = {
@@ -1092,19 +1072,18 @@ export const getCopilotRecentSessionsQuery = {
query: `query getCopilotRecentSessions($workspaceId: String!, $limit: Int = 10) { query: `query getCopilotRecentSessions($workspaceId: String!, $limit: Int = 10) {
currentUser { currentUser {
copilot(workspaceId: $workspaceId) { copilot(workspaceId: $workspaceId) {
histories(options: {limit: $limit, sessionOrder: desc}) { chats(
sessionId pagination: {first: $limit}
workspaceId options: {fork: false, sessionOrder: desc, withMessages: true}
docId ) {
pinned ...PaginatedCopilotChats
action
tokens
createdAt
updatedAt
} }
} }
} }
}`, }
${copilotChatMessageFragment}
${copilotChatHistoryFragment}
${paginatedCopilotChatsFragment}`,
}; };
export const updateCopilotSessionMutation = { export const updateCopilotSessionMutation = {
@@ -1118,22 +1097,18 @@ export const updateCopilotSessionMutation = {
export const getCopilotSessionsQuery = { export const getCopilotSessionsQuery = {
id: 'getCopilotSessionsQuery' as const, id: 'getCopilotSessionsQuery' as const,
op: 'getCopilotSessions', op: 'getCopilotSessions',
query: `query getCopilotSessions($workspaceId: String!, $docId: String, $options: QueryChatSessionsInput) { query: `query getCopilotSessions($workspaceId: String!, $pagination: PaginationInput!, $docId: String, $options: QueryChatHistoriesInput) {
currentUser { currentUser {
copilot(workspaceId: $workspaceId) { copilot(workspaceId: $workspaceId) {
sessions(docId: $docId, options: $options) { chats(pagination: $pagination, docId: $docId, options: $options) {
id ...PaginatedCopilotChats
parentSessionId
docId
pinned
title
promptName
model
optionalModels
} }
} }
} }
}`, }
${copilotChatMessageFragment}
${copilotChatHistoryFragment}
${paginatedCopilotChatsFragment}`,
}; };
export const addWorkspaceEmbeddingFilesMutation = { export const addWorkspaceEmbeddingFilesMutation = {
+531 -159
View File
@@ -245,14 +245,19 @@ export interface ContextWorkspaceEmbeddingStatus {
export interface Copilot { export interface Copilot {
__typename?: 'Copilot'; __typename?: 'Copilot';
audioTranscription: Maybe<TranscriptionResultType>; audioTranscription: Maybe<TranscriptionResultType>;
chats: PaginatedCopilotHistoriesType;
/** Get the context list of a session */ /** Get the context list of a session */
contexts: Array<CopilotContext>; contexts: Array<CopilotContext>;
/** @deprecated use `chats` instead */
histories: Array<CopilotHistories>; histories: Array<CopilotHistories>;
/** Get the quota of the user in the workspace */ /** Get the quota of the user in the workspace */
quota: CopilotQuota; quota: CopilotQuota;
/** Get the session by id */ /** Get the session by id */
session: CopilotSessionType; session: CopilotSessionType;
/** Get the session list in the workspace */ /**
* Get the session list in the workspace
* @deprecated use `chats` instead
*/
sessions: Array<CopilotSessionType>; sessions: Array<CopilotSessionType>;
workspaceId: Maybe<Scalars['ID']['output']>; workspaceId: Maybe<Scalars['ID']['output']>;
} }
@@ -262,6 +267,12 @@ export interface CopilotAudioTranscriptionArgs {
jobId?: InputMaybe<Scalars['String']['input']>; jobId?: InputMaybe<Scalars['String']['input']>;
} }
export interface CopilotChatsArgs {
docId?: InputMaybe<Scalars['String']['input']>;
options?: InputMaybe<QueryChatHistoriesInput>;
pagination: PaginationInput;
}
export interface CopilotContextsArgs { export interface CopilotContextsArgs {
contextId?: InputMaybe<Scalars['String']['input']>; contextId?: InputMaybe<Scalars['String']['input']>;
sessionId?: InputMaybe<Scalars['String']['input']>; sessionId?: InputMaybe<Scalars['String']['input']>;
@@ -391,14 +402,25 @@ export interface CopilotHistories {
createdAt: Scalars['DateTime']['output']; createdAt: Scalars['DateTime']['output'];
docId: Maybe<Scalars['String']['output']>; docId: Maybe<Scalars['String']['output']>;
messages: Array<ChatMessage>; messages: Array<ChatMessage>;
model: Scalars['String']['output'];
optionalModels: Array<Scalars['String']['output']>;
parentSessionId: Maybe<Scalars['String']['output']>;
pinned: Scalars['Boolean']['output']; pinned: Scalars['Boolean']['output'];
promptName: Scalars['String']['output'];
sessionId: Scalars['String']['output']; sessionId: Scalars['String']['output'];
title: Maybe<Scalars['String']['output']>;
/** The number of tokens used in the session */ /** The number of tokens used in the session */
tokens: Scalars['Int']['output']; tokens: Scalars['Int']['output'];
updatedAt: Scalars['DateTime']['output']; updatedAt: Scalars['DateTime']['output'];
workspaceId: Scalars['String']['output']; workspaceId: Scalars['String']['output'];
} }
export interface CopilotHistoriesTypeEdge {
__typename?: 'CopilotHistoriesTypeEdge';
cursor: Scalars['String']['output'];
node: CopilotHistories;
}
export interface CopilotInvalidContextDataType { export interface CopilotInvalidContextDataType {
__typename?: 'CopilotInvalidContextDataType'; __typename?: 'CopilotInvalidContextDataType';
contextId: Scalars['String']['output']; contextId: Scalars['String']['output'];
@@ -1954,6 +1976,13 @@ export interface PaginatedCommentObjectType {
totalCount: Scalars['Int']['output']; totalCount: Scalars['Int']['output'];
} }
export interface PaginatedCopilotHistoriesType {
__typename?: 'PaginatedCopilotHistoriesType';
edges: Array<CopilotHistoriesTypeEdge>;
pageInfo: PageInfo;
totalCount: Scalars['Int']['output'];
}
export interface PaginatedCopilotWorkspaceFileType { export interface PaginatedCopilotWorkspaceFileType {
__typename?: 'PaginatedCopilotWorkspaceFileType'; __typename?: 'PaginatedCopilotWorkspaceFileType';
edges: Array<CopilotWorkspaceFileTypeEdge>; edges: Array<CopilotWorkspaceFileTypeEdge>;
@@ -2133,6 +2162,7 @@ export interface QueryChatHistoriesInput {
sessionId?: InputMaybe<Scalars['String']['input']>; sessionId?: InputMaybe<Scalars['String']['input']>;
sessionOrder?: InputMaybe<ChatHistoryOrder>; sessionOrder?: InputMaybe<ChatHistoryOrder>;
skip?: InputMaybe<Scalars['Int']['input']>; skip?: InputMaybe<Scalars['Int']['input']>;
withMessages?: InputMaybe<Scalars['Boolean']['input']>;
withPrompt?: InputMaybe<Scalars['Boolean']['input']>; withPrompt?: InputMaybe<Scalars['Boolean']['input']>;
} }
@@ -3757,6 +3787,7 @@ export type QueueWorkspaceEmbeddingMutation = {
export type GetCopilotHistoryIdsQueryVariables = Exact<{ export type GetCopilotHistoryIdsQueryVariables = Exact<{
workspaceId: Scalars['String']['input']; workspaceId: Scalars['String']['input'];
pagination: PaginationInput;
docId?: InputMaybe<Scalars['String']['input']>; docId?: InputMaybe<Scalars['String']['input']>;
options?: InputMaybe<QueryChatHistoriesInput>; options?: InputMaybe<QueryChatHistoriesInput>;
}>; }>;
@@ -3767,17 +3798,31 @@ export type GetCopilotHistoryIdsQuery = {
__typename?: 'UserType'; __typename?: 'UserType';
copilot: { copilot: {
__typename?: 'Copilot'; __typename?: 'Copilot';
histories: Array<{ chats: {
__typename?: 'CopilotHistories'; __typename?: 'PaginatedCopilotHistoriesType';
sessionId: string; pageInfo: {
pinned: boolean; __typename?: 'PageInfo';
messages: Array<{ hasNextPage: boolean;
__typename?: 'ChatMessage'; hasPreviousPage: boolean;
id: string | null; startCursor: string | null;
role: string; endCursor: string | null;
createdAt: string; };
edges: Array<{
__typename?: 'CopilotHistoriesTypeEdge';
cursor: string;
node: {
__typename?: 'CopilotHistories';
sessionId: string;
pinned: boolean;
messages: Array<{
__typename?: 'ChatMessage';
id: string | null;
role: string;
createdAt: string;
}>;
};
}>; }>;
}>; };
}; };
} | null; } | null;
}; };
@@ -3785,6 +3830,7 @@ export type GetCopilotHistoryIdsQuery = {
export type GetCopilotDocSessionsQueryVariables = Exact<{ export type GetCopilotDocSessionsQueryVariables = Exact<{
workspaceId: Scalars['String']['input']; workspaceId: Scalars['String']['input'];
docId: Scalars['String']['input']; docId: Scalars['String']['input'];
pagination: PaginationInput;
options?: InputMaybe<QueryChatHistoriesInput>; options?: InputMaybe<QueryChatHistoriesInput>;
}>; }>;
@@ -3794,31 +3840,53 @@ export type GetCopilotDocSessionsQuery = {
__typename?: 'UserType'; __typename?: 'UserType';
copilot: { copilot: {
__typename?: 'Copilot'; __typename?: 'Copilot';
histories: Array<{ chats: {
__typename?: 'CopilotHistories'; __typename?: 'PaginatedCopilotHistoriesType';
sessionId: string; pageInfo: {
pinned: boolean; __typename?: 'PageInfo';
tokens: number; hasNextPage: boolean;
action: string | null; hasPreviousPage: boolean;
createdAt: string; startCursor: string | null;
messages: Array<{ endCursor: string | null;
__typename?: 'ChatMessage'; };
id: string | null; edges: Array<{
role: string; __typename?: 'CopilotHistoriesTypeEdge';
content: string; cursor: string;
attachments: Array<string> | null; node: {
createdAt: string; __typename?: 'CopilotHistories';
streamObjects: Array<{ sessionId: string;
__typename?: 'StreamObject'; workspaceId: string;
type: string; docId: string | null;
textDelta: string | null; parentSessionId: string | null;
toolCallId: string | null; promptName: string;
toolName: string | null; model: string;
args: Record<string, string> | null; optionalModels: Array<string>;
result: Record<string, string> | null; action: string | null;
}> | null; pinned: boolean;
title: string | null;
tokens: number;
createdAt: string;
updatedAt: string;
messages: Array<{
__typename?: 'ChatMessage';
id: string | null;
role: string;
content: string;
attachments: Array<string> | null;
createdAt: string;
streamObjects: Array<{
__typename?: 'StreamObject';
type: string;
textDelta: string | null;
toolCallId: string | null;
toolName: string | null;
args: Record<string, string> | null;
result: Record<string, string> | null;
}> | null;
}>;
};
}>; }>;
}>; };
}; };
} | null; } | null;
}; };
@@ -3836,37 +3904,60 @@ export type GetCopilotPinnedSessionsQuery = {
__typename?: 'UserType'; __typename?: 'UserType';
copilot: { copilot: {
__typename?: 'Copilot'; __typename?: 'Copilot';
histories: Array<{ chats: {
__typename?: 'CopilotHistories'; __typename?: 'PaginatedCopilotHistoriesType';
sessionId: string; pageInfo: {
pinned: boolean; __typename?: 'PageInfo';
tokens: number; hasNextPage: boolean;
action: string | null; hasPreviousPage: boolean;
createdAt: string; startCursor: string | null;
messages: Array<{ endCursor: string | null;
__typename?: 'ChatMessage'; };
id: string | null; edges: Array<{
role: string; __typename?: 'CopilotHistoriesTypeEdge';
content: string; cursor: string;
attachments: Array<string> | null; node: {
createdAt: string; __typename?: 'CopilotHistories';
streamObjects: Array<{ sessionId: string;
__typename?: 'StreamObject'; workspaceId: string;
type: string; docId: string | null;
textDelta: string | null; parentSessionId: string | null;
toolCallId: string | null; promptName: string;
toolName: string | null; model: string;
args: Record<string, string> | null; optionalModels: Array<string>;
result: Record<string, string> | null; action: string | null;
}> | null; pinned: boolean;
title: string | null;
tokens: number;
createdAt: string;
updatedAt: string;
messages: Array<{
__typename?: 'ChatMessage';
id: string | null;
role: string;
content: string;
attachments: Array<string> | null;
createdAt: string;
streamObjects: Array<{
__typename?: 'StreamObject';
type: string;
textDelta: string | null;
toolCallId: string | null;
toolName: string | null;
args: Record<string, string> | null;
result: Record<string, string> | null;
}> | null;
}>;
};
}>; }>;
}>; };
}; };
} | null; } | null;
}; };
export type GetCopilotWorkspaceSessionsQueryVariables = Exact<{ export type GetCopilotWorkspaceSessionsQueryVariables = Exact<{
workspaceId: Scalars['String']['input']; workspaceId: Scalars['String']['input'];
pagination: PaginationInput;
options?: InputMaybe<QueryChatHistoriesInput>; options?: InputMaybe<QueryChatHistoriesInput>;
}>; }>;
@@ -3876,37 +3967,60 @@ export type GetCopilotWorkspaceSessionsQuery = {
__typename?: 'UserType'; __typename?: 'UserType';
copilot: { copilot: {
__typename?: 'Copilot'; __typename?: 'Copilot';
histories: Array<{ chats: {
__typename?: 'CopilotHistories'; __typename?: 'PaginatedCopilotHistoriesType';
sessionId: string; pageInfo: {
pinned: boolean; __typename?: 'PageInfo';
tokens: number; hasNextPage: boolean;
action: string | null; hasPreviousPage: boolean;
createdAt: string; startCursor: string | null;
messages: Array<{ endCursor: string | null;
__typename?: 'ChatMessage'; };
id: string | null; edges: Array<{
role: string; __typename?: 'CopilotHistoriesTypeEdge';
content: string; cursor: string;
attachments: Array<string> | null; node: {
createdAt: string; __typename?: 'CopilotHistories';
streamObjects: Array<{ sessionId: string;
__typename?: 'StreamObject'; workspaceId: string;
type: string; docId: string | null;
textDelta: string | null; parentSessionId: string | null;
toolCallId: string | null; promptName: string;
toolName: string | null; model: string;
args: Record<string, string> | null; optionalModels: Array<string>;
result: Record<string, string> | null; action: string | null;
}> | null; pinned: boolean;
title: string | null;
tokens: number;
createdAt: string;
updatedAt: string;
messages: Array<{
__typename?: 'ChatMessage';
id: string | null;
role: string;
content: string;
attachments: Array<string> | null;
createdAt: string;
streamObjects: Array<{
__typename?: 'StreamObject';
type: string;
textDelta: string | null;
toolCallId: string | null;
toolName: string | null;
args: Record<string, string> | null;
result: Record<string, string> | null;
}> | null;
}>;
};
}>; }>;
}>; };
}; };
} | null; } | null;
}; };
export type GetCopilotHistoriesQueryVariables = Exact<{ export type GetCopilotHistoriesQueryVariables = Exact<{
workspaceId: Scalars['String']['input']; workspaceId: Scalars['String']['input'];
pagination: PaginationInput;
docId?: InputMaybe<Scalars['String']['input']>; docId?: InputMaybe<Scalars['String']['input']>;
options?: InputMaybe<QueryChatHistoriesInput>; options?: InputMaybe<QueryChatHistoriesInput>;
}>; }>;
@@ -3917,31 +4031,53 @@ export type GetCopilotHistoriesQuery = {
__typename?: 'UserType'; __typename?: 'UserType';
copilot: { copilot: {
__typename?: 'Copilot'; __typename?: 'Copilot';
histories: Array<{ chats: {
__typename?: 'CopilotHistories'; __typename?: 'PaginatedCopilotHistoriesType';
sessionId: string; pageInfo: {
pinned: boolean; __typename?: 'PageInfo';
tokens: number; hasNextPage: boolean;
action: string | null; hasPreviousPage: boolean;
createdAt: string; startCursor: string | null;
messages: Array<{ endCursor: string | null;
__typename?: 'ChatMessage'; };
id: string | null; edges: Array<{
role: string; __typename?: 'CopilotHistoriesTypeEdge';
content: string; cursor: string;
attachments: Array<string> | null; node: {
createdAt: string; __typename?: 'CopilotHistories';
streamObjects: Array<{ sessionId: string;
__typename?: 'StreamObject'; workspaceId: string;
type: string; docId: string | null;
textDelta: string | null; parentSessionId: string | null;
toolCallId: string | null; promptName: string;
toolName: string | null; model: string;
args: Record<string, string> | null; optionalModels: Array<string>;
result: Record<string, string> | null; action: string | null;
}> | null; pinned: boolean;
title: string | null;
tokens: number;
createdAt: string;
updatedAt: string;
messages: Array<{
__typename?: 'ChatMessage';
id: string | null;
role: string;
content: string;
attachments: Array<string> | null;
createdAt: string;
streamObjects: Array<{
__typename?: 'StreamObject';
type: string;
textDelta: string | null;
toolCallId: string | null;
toolName: string | null;
args: Record<string, string> | null;
result: Record<string, string> | null;
}> | null;
}>;
};
}>; }>;
}>; };
}; };
} | null; } | null;
}; };
@@ -4095,26 +4231,53 @@ export type GetCopilotLatestDocSessionQuery = {
__typename?: 'UserType'; __typename?: 'UserType';
copilot: { copilot: {
__typename?: 'Copilot'; __typename?: 'Copilot';
histories: Array<{ chats: {
__typename?: 'CopilotHistories'; __typename?: 'PaginatedCopilotHistoriesType';
sessionId: string; pageInfo: {
workspaceId: string; __typename?: 'PageInfo';
docId: string | null; hasNextPage: boolean;
pinned: boolean; hasPreviousPage: boolean;
action: string | null; startCursor: string | null;
tokens: number; endCursor: string | null;
createdAt: string; };
updatedAt: string; edges: Array<{
messages: Array<{ __typename?: 'CopilotHistoriesTypeEdge';
__typename?: 'ChatMessage'; cursor: string;
id: string | null; node: {
role: string; __typename?: 'CopilotHistories';
content: string; sessionId: string;
attachments: Array<string> | null; workspaceId: string;
params: Record<string, string> | null; docId: string | null;
createdAt: string; parentSessionId: string | null;
promptName: string;
model: string;
optionalModels: Array<string>;
action: string | null;
pinned: boolean;
title: string | null;
tokens: number;
createdAt: string;
updatedAt: string;
messages: Array<{
__typename?: 'ChatMessage';
id: string | null;
role: string;
content: string;
attachments: Array<string> | null;
createdAt: string;
streamObjects: Array<{
__typename?: 'StreamObject';
type: string;
textDelta: string | null;
toolCallId: string | null;
toolName: string | null;
args: Record<string, string> | null;
result: Record<string, string> | null;
}> | null;
}>;
};
}>; }>;
}>; };
}; };
} | null; } | null;
}; };
@@ -4130,16 +4293,52 @@ export type GetCopilotSessionQuery = {
__typename?: 'UserType'; __typename?: 'UserType';
copilot: { copilot: {
__typename?: 'Copilot'; __typename?: 'Copilot';
session: { chats: {
__typename?: 'CopilotSessionType'; __typename?: 'PaginatedCopilotHistoriesType';
id: string; pageInfo: {
parentSessionId: string | null; __typename?: 'PageInfo';
docId: string | null; hasNextPage: boolean;
pinned: boolean; hasPreviousPage: boolean;
title: string | null; startCursor: string | null;
promptName: string; endCursor: string | null;
model: string; };
optionalModels: Array<string>; edges: Array<{
__typename?: 'CopilotHistoriesTypeEdge';
cursor: string;
node: {
__typename?: 'CopilotHistories';
sessionId: string;
workspaceId: string;
docId: string | null;
parentSessionId: string | null;
promptName: string;
model: string;
optionalModels: Array<string>;
action: string | null;
pinned: boolean;
title: string | null;
tokens: number;
createdAt: string;
updatedAt: string;
messages: Array<{
__typename?: 'ChatMessage';
id: string | null;
role: string;
content: string;
attachments: Array<string> | null;
createdAt: string;
streamObjects: Array<{
__typename?: 'StreamObject';
type: string;
textDelta: string | null;
toolCallId: string | null;
toolName: string | null;
args: Record<string, string> | null;
result: Record<string, string> | null;
}> | null;
}>;
};
}>;
}; };
}; };
} | null; } | null;
@@ -4156,17 +4355,53 @@ export type GetCopilotRecentSessionsQuery = {
__typename?: 'UserType'; __typename?: 'UserType';
copilot: { copilot: {
__typename?: 'Copilot'; __typename?: 'Copilot';
histories: Array<{ chats: {
__typename?: 'CopilotHistories'; __typename?: 'PaginatedCopilotHistoriesType';
sessionId: string; pageInfo: {
workspaceId: string; __typename?: 'PageInfo';
docId: string | null; hasNextPage: boolean;
pinned: boolean; hasPreviousPage: boolean;
action: string | null; startCursor: string | null;
tokens: number; endCursor: string | null;
createdAt: string; };
updatedAt: string; edges: Array<{
}>; __typename?: 'CopilotHistoriesTypeEdge';
cursor: string;
node: {
__typename?: 'CopilotHistories';
sessionId: string;
workspaceId: string;
docId: string | null;
parentSessionId: string | null;
promptName: string;
model: string;
optionalModels: Array<string>;
action: string | null;
pinned: boolean;
title: string | null;
tokens: number;
createdAt: string;
updatedAt: string;
messages: Array<{
__typename?: 'ChatMessage';
id: string | null;
role: string;
content: string;
attachments: Array<string> | null;
createdAt: string;
streamObjects: Array<{
__typename?: 'StreamObject';
type: string;
textDelta: string | null;
toolCallId: string | null;
toolName: string | null;
args: Record<string, string> | null;
result: Record<string, string> | null;
}> | null;
}>;
};
}>;
};
}; };
} | null; } | null;
}; };
@@ -4182,8 +4417,9 @@ export type UpdateCopilotSessionMutation = {
export type GetCopilotSessionsQueryVariables = Exact<{ export type GetCopilotSessionsQueryVariables = Exact<{
workspaceId: Scalars['String']['input']; workspaceId: Scalars['String']['input'];
pagination: PaginationInput;
docId?: InputMaybe<Scalars['String']['input']>; docId?: InputMaybe<Scalars['String']['input']>;
options?: InputMaybe<QueryChatSessionsInput>; options?: InputMaybe<QueryChatHistoriesInput>;
}>; }>;
export type GetCopilotSessionsQuery = { export type GetCopilotSessionsQuery = {
@@ -4192,17 +4428,53 @@ export type GetCopilotSessionsQuery = {
__typename?: 'UserType'; __typename?: 'UserType';
copilot: { copilot: {
__typename?: 'Copilot'; __typename?: 'Copilot';
sessions: Array<{ chats: {
__typename?: 'CopilotSessionType'; __typename?: 'PaginatedCopilotHistoriesType';
id: string; pageInfo: {
parentSessionId: string | null; __typename?: 'PageInfo';
docId: string | null; hasNextPage: boolean;
pinned: boolean; hasPreviousPage: boolean;
title: string | null; startCursor: string | null;
promptName: string; endCursor: string | null;
model: string; };
optionalModels: Array<string>; edges: Array<{
}>; __typename?: 'CopilotHistoriesTypeEdge';
cursor: string;
node: {
__typename?: 'CopilotHistories';
sessionId: string;
workspaceId: string;
docId: string | null;
parentSessionId: string | null;
promptName: string;
model: string;
optionalModels: Array<string>;
action: string | null;
pinned: boolean;
title: string | null;
tokens: number;
createdAt: string;
updatedAt: string;
messages: Array<{
__typename?: 'ChatMessage';
id: string | null;
role: string;
content: string;
attachments: Array<string> | null;
createdAt: string;
streamObjects: Array<{
__typename?: 'StreamObject';
type: string;
textDelta: string | null;
toolCallId: string | null;
toolName: string | null;
args: Record<string, string> | null;
result: Record<string, string> | null;
}> | null;
}>;
};
}>;
};
}; };
} | null; } | null;
}; };
@@ -4438,6 +4710,106 @@ export type GetDocRolePermissionsQuery = {
}; };
}; };
export type CopilotChatMessageFragment = {
__typename?: 'ChatMessage';
id: string | null;
role: string;
content: string;
attachments: Array<string> | null;
createdAt: string;
streamObjects: Array<{
__typename?: 'StreamObject';
type: string;
textDelta: string | null;
toolCallId: string | null;
toolName: string | null;
args: Record<string, string> | null;
result: Record<string, string> | null;
}> | null;
};
export type CopilotChatHistoryFragment = {
__typename?: 'CopilotHistories';
sessionId: string;
workspaceId: string;
docId: string | null;
parentSessionId: string | null;
promptName: string;
model: string;
optionalModels: Array<string>;
action: string | null;
pinned: boolean;
title: string | null;
tokens: number;
createdAt: string;
updatedAt: string;
messages: Array<{
__typename?: 'ChatMessage';
id: string | null;
role: string;
content: string;
attachments: Array<string> | null;
createdAt: string;
streamObjects: Array<{
__typename?: 'StreamObject';
type: string;
textDelta: string | null;
toolCallId: string | null;
toolName: string | null;
args: Record<string, string> | null;
result: Record<string, string> | null;
}> | null;
}>;
};
export type PaginatedCopilotChatsFragment = {
__typename?: 'PaginatedCopilotHistoriesType';
pageInfo: {
__typename?: 'PageInfo';
hasNextPage: boolean;
hasPreviousPage: boolean;
startCursor: string | null;
endCursor: string | null;
};
edges: Array<{
__typename?: 'CopilotHistoriesTypeEdge';
cursor: string;
node: {
__typename?: 'CopilotHistories';
sessionId: string;
workspaceId: string;
docId: string | null;
parentSessionId: string | null;
promptName: string;
model: string;
optionalModels: Array<string>;
action: string | null;
pinned: boolean;
title: string | null;
tokens: number;
createdAt: string;
updatedAt: string;
messages: Array<{
__typename?: 'ChatMessage';
id: string | null;
role: string;
content: string;
attachments: Array<string> | null;
createdAt: string;
streamObjects: Array<{
__typename?: 'StreamObject';
type: string;
textDelta: string | null;
toolCallId: string | null;
toolName: string | null;
args: Record<string, string> | null;
result: Record<string, string> | null;
}> | null;
}>;
};
}>;
};
export type CredentialsRequirementsFragment = { export type CredentialsRequirementsFragment = {
__typename?: 'CredentialsRequirementType'; __typename?: 'CredentialsRequirementType';
password: { password: {
@@ -2,13 +2,13 @@ import type {
ContextMatchedDocChunk, ContextMatchedDocChunk,
ContextMatchedFileChunk, ContextMatchedFileChunk,
ContextWorkspaceEmbeddingStatus, ContextWorkspaceEmbeddingStatus,
CopilotChatHistoryFragment,
CopilotContextCategory, CopilotContextCategory,
CopilotContextDoc, CopilotContextDoc,
CopilotContextFile, CopilotContextFile,
CopilotHistories, CopilotHistories,
CopilotSessionType,
getCopilotHistoriesQuery, getCopilotHistoriesQuery,
QueryChatSessionsInput, QueryChatHistoriesInput,
RequestOptions, RequestOptions,
StreamObject, StreamObject,
UpdateChatSessionInput, UpdateChatSessionInput,
@@ -356,10 +356,10 @@ declare global {
interface AIHistory { interface AIHistory {
sessionId: string; sessionId: string;
tokens: number; tokens: number;
action: string; action: string | null;
createdAt: string; createdAt: string;
messages: { messages: {
id: string; // message id id: string | null; // message id
content: string; content: string;
createdAt: string; createdAt: string;
role: MessageRole; role: MessageRole;
@@ -392,19 +392,19 @@ declare global {
interface AISessionService { interface AISessionService {
createSession: (options: AICreateSessionOptions) => Promise<string>; createSession: (options: AICreateSessionOptions) => Promise<string>;
getSession: (
workspaceId: string,
sessionId: string
) => Promise<CopilotChatHistoryFragment | undefined>;
getSessions: ( getSessions: (
workspaceId: string, workspaceId: string,
docId?: string, docId?: string,
options?: QueryChatSessionsInput options?: QueryChatHistoriesInput
) => Promise<CopilotSessionType[] | undefined>; ) => Promise<CopilotChatHistoryFragment[] | undefined>;
getRecentSessions: ( getRecentSessions: (
workspaceId: string, workspaceId: string,
limit?: number limit?: number
) => Promise<AIRecentSession[] | undefined>; ) => Promise<AIRecentSession[] | undefined>;
getSession: (
workspaceId: string,
sessionId: string
) => Promise<CopilotSessionType | undefined>;
updateSession: (options: UpdateChatSessionInput) => Promise<string>; updateSession: (options: UpdateChatSessionInput) => Promise<string>;
} }
@@ -3,7 +3,7 @@ import type { FeatureFlagService } from '@affine/core/modules/feature-flag';
import type { WorkbenchService } from '@affine/core/modules/workbench'; import type { WorkbenchService } from '@affine/core/modules/workbench';
import type { import type {
ContextEmbedStatus, ContextEmbedStatus,
CopilotSessionType, CopilotChatHistoryFragment,
UpdateChatSessionInput, UpdateChatSessionInput,
} from '@affine/graphql'; } from '@affine/graphql';
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit'; import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
@@ -103,7 +103,7 @@ export class ChatPanel extends SignalWatcher(
accessor affineWorkbenchService!: WorkbenchService; accessor affineWorkbenchService!: WorkbenchService;
@state() @state()
accessor session: CopilotSessionType | null | undefined; accessor session: CopilotChatHistoryFragment | null | undefined;
@state() @state()
accessor embeddingProgress: [number, number] = [0, 0]; accessor embeddingProgress: [number, number] = [0, 0];
@@ -170,7 +170,7 @@ export class ChatPanel extends SignalWatcher(
}; };
private readonly setSession = ( private readonly setSession = (
session: CopilotSessionType | null | undefined session: CopilotChatHistoryFragment | null | undefined
) => { ) => {
this.session = session ?? null; this.session = session ?? null;
}; };
@@ -250,7 +250,7 @@ export class ChatPanel extends SignalWatcher(
}; };
private readonly openSession = async (sessionId: string) => { private readonly openSession = async (sessionId: string) => {
if (this.session?.id === sessionId) { if (this.session?.sessionId === sessionId) {
return; return;
} }
this.resetPanel(); this.resetPanel();
@@ -263,7 +263,7 @@ export class ChatPanel extends SignalWatcher(
private readonly openDoc = async (docId: string, sessionId: string) => { private readonly openDoc = async (docId: string, sessionId: string) => {
if (this.doc.id === docId) { if (this.doc.id === docId) {
if (this.session?.id === sessionId || this.session?.pinned) { if (this.session?.sessionId === sessionId || this.session?.pinned) {
return; return;
} }
await this.openSession(sessionId); await this.openSession(sessionId);
@@ -284,7 +284,7 @@ export class ChatPanel extends SignalWatcher(
await this.createSession({ pinned }); await this.createSession({ pinned });
} else { } else {
await this.updateSession({ await this.updateSession({
sessionId: this.session.id, sessionId: this.session.sessionId,
pinned, pinned,
}); });
} }
@@ -296,7 +296,7 @@ export class ChatPanel extends SignalWatcher(
} }
if (this.session.docId !== this.doc.id) { if (this.session.docId !== this.doc.id) {
await this.updateSession({ await this.updateSession({
sessionId: this.session.id, sessionId: this.session.sessionId,
docId: this.doc.id, docId: this.doc.id,
}); });
} }
@@ -399,7 +399,7 @@ export class ChatPanel extends SignalWatcher(
return html`<div class="chat-panel-container"> return html`<div class="chat-panel-container">
${keyed( ${keyed(
this.hasPinned ? this.session?.id : this.doc.id, this.hasPinned ? this.session?.sessionId : this.doc.id,
html`<ai-chat-content html`<ai-chat-content
.chatTitle=${this.chatTitle} .chatTitle=${this.chatTitle}
.host=${this.host} .host=${this.host}
@@ -1,5 +1,5 @@
import type { FeatureFlagService } from '@affine/core/modules/feature-flag'; import type { FeatureFlagService } from '@affine/core/modules/feature-flag';
import type { CopilotSessionType } from '@affine/graphql'; import type { CopilotChatHistoryFragment } from '@affine/graphql';
import { WithDisposable } from '@blocksuite/affine/global/lit'; import { WithDisposable } from '@blocksuite/affine/global/lit';
import { isInsidePageEditor } from '@blocksuite/affine/shared/utils'; import { isInsidePageEditor } from '@blocksuite/affine/shared/utils';
import type { EditorHost } from '@blocksuite/affine/std'; import type { EditorHost } from '@blocksuite/affine/std';
@@ -57,7 +57,7 @@ export class ChatMessageAssistant extends WithDisposable(ShadowlessElement) {
accessor affineFeatureFlagService!: FeatureFlagService; accessor affineFeatureFlagService!: FeatureFlagService;
@property({ attribute: false }) @property({ attribute: false })
accessor session!: CopilotSessionType | null | undefined; accessor session!: CopilotChatHistoryFragment | null | undefined;
@property({ attribute: false }) @property({ attribute: false })
accessor retry!: () => void; accessor retry!: () => void;
@@ -4,10 +4,10 @@ import type { WorkspaceDialogService } from '@affine/core/modules/dialogs';
import type { import type {
ContextEmbedStatus, ContextEmbedStatus,
ContextWorkspaceEmbeddingStatus, ContextWorkspaceEmbeddingStatus,
CopilotChatHistoryFragment,
CopilotContextDoc, CopilotContextDoc,
CopilotContextFile, CopilotContextFile,
CopilotDocType, CopilotDocType,
CopilotSessionType,
} from '@affine/graphql'; } from '@affine/graphql';
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit'; import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
import type { EditorHost } from '@blocksuite/affine/std'; import type { EditorHost } from '@blocksuite/affine/std';
@@ -63,10 +63,12 @@ export class AIChatComposer extends SignalWatcher(
accessor docId: string | undefined; accessor docId: string | undefined;
@property({ attribute: false }) @property({ attribute: false })
accessor session!: CopilotSessionType | null | undefined; accessor session!: CopilotChatHistoryFragment | null | undefined;
@property({ attribute: false }) @property({ attribute: false })
accessor createSession!: () => Promise<CopilotSessionType | undefined>; accessor createSession!: () => Promise<
CopilotChatHistoryFragment | undefined
>;
@property({ attribute: false }) @property({ attribute: false })
accessor chatContextValue!: AIChatInputContext; accessor chatContextValue!: AIChatInputContext;
@@ -178,7 +180,7 @@ export class AIChatComposer extends SignalWatcher(
return this._contextId; return this._contextId;
} }
const sessionId = this.session?.id; const sessionId = this.session?.sessionId;
if (!sessionId) return; if (!sessionId) return;
const contextId = await AIProvider.context?.getContextId( const contextId = await AIProvider.context?.getContextId(
@@ -194,7 +196,7 @@ export class AIChatComposer extends SignalWatcher(
return this._contextId; return this._contextId;
} }
const sessionId = (await this.createSession())?.id; const sessionId = (await this.createSession())?.sessionId;
if (!sessionId) return; if (!sessionId) return;
this._contextId = await AIProvider.context?.createContext( this._contextId = await AIProvider.context?.createContext(
@@ -206,7 +208,7 @@ export class AIChatComposer extends SignalWatcher(
private readonly _initChips = async () => { private readonly _initChips = async () => {
// context not initialized // context not initialized
const sessionId = this.session?.id; const sessionId = this.session?.sessionId;
const contextId = await this._getContextId(); const contextId = await this._getContextId();
if (!sessionId || !contextId) { if (!sessionId || !contextId) {
return; return;
@@ -282,7 +284,7 @@ export class AIChatComposer extends SignalWatcher(
}; };
private readonly _pollContextDocsAndFiles = async () => { private readonly _pollContextDocsAndFiles = async () => {
const sessionId = this.session?.id; const sessionId = this.session?.sessionId;
const contextId = await this._getContextId(); const contextId = await this._getContextId();
if (!sessionId || !contextId || !AIProvider.context) { if (!sessionId || !contextId || !AIProvider.context) {
return; return;
@@ -1,6 +1,9 @@
import type { WorkspaceDialogService } from '@affine/core/modules/dialogs'; import type { WorkspaceDialogService } from '@affine/core/modules/dialogs';
import type { FeatureFlagService } from '@affine/core/modules/feature-flag'; import type { FeatureFlagService } from '@affine/core/modules/feature-flag';
import type { ContextEmbedStatus, CopilotSessionType } from '@affine/graphql'; import type {
ContextEmbedStatus,
CopilotChatHistoryFragment,
} from '@affine/graphql';
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit'; import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
import type { EditorHost } from '@blocksuite/affine/std'; import type { EditorHost } from '@blocksuite/affine/std';
import { ShadowlessElement } from '@blocksuite/affine/std'; import { ShadowlessElement } from '@blocksuite/affine/std';
@@ -123,10 +126,12 @@ export class AIChatContent extends SignalWatcher(
accessor host: EditorHost | null | undefined; accessor host: EditorHost | null | undefined;
@property({ attribute: false }) @property({ attribute: false })
accessor session!: CopilotSessionType | null | undefined; accessor session!: CopilotChatHistoryFragment | null | undefined;
@property({ attribute: false }) @property({ attribute: false })
accessor createSession!: () => Promise<CopilotSessionType | undefined>; accessor createSession!: () => Promise<
CopilotChatHistoryFragment | undefined
>;
@property({ attribute: false }) @property({ attribute: false })
accessor workspaceId!: string; accessor workspaceId!: string;
@@ -214,7 +219,7 @@ export class AIChatContent extends SignalWatcher(
return; return;
} }
const sessionId = this.session?.id; const sessionId = this.session?.sessionId;
const [histories, actions] = await Promise.all([ const [histories, actions] = await Promise.all([
sessionId sessionId
? AIProvider.histories.chats(this.workspaceId, sessionId) ? AIProvider.histories.chats(this.workspaceId, sessionId)
@@ -1,5 +1,5 @@
import { toast } from '@affine/component'; import { toast } from '@affine/component';
import type { CopilotSessionType } from '@affine/graphql'; import type { CopilotChatHistoryFragment } from '@affine/graphql';
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit'; import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
import { unsafeCSSVar, unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme'; import { unsafeCSSVar, unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
import { openFilesWith } from '@blocksuite/affine/shared/utils'; import { openFilesWith } from '@blocksuite/affine/shared/utils';
@@ -304,7 +304,7 @@ export class AIChatInput extends SignalWatcher(
accessor docId: string | undefined; accessor docId: string | undefined;
@property({ attribute: false }) @property({ attribute: false })
accessor session!: CopilotSessionType | null | undefined; accessor session!: CopilotChatHistoryFragment | null | undefined;
@query('image-preview-grid') @query('image-preview-grid')
accessor imagePreviewGrid: HTMLDivElement | null = null; accessor imagePreviewGrid: HTMLDivElement | null = null;
@@ -328,7 +328,9 @@ export class AIChatInput extends SignalWatcher(
accessor chips: ChatChip[] = []; accessor chips: ChatChip[] = [];
@property({ attribute: false }) @property({ attribute: false })
accessor createSession!: () => Promise<CopilotSessionType | undefined>; accessor createSession!: () => Promise<
CopilotChatHistoryFragment | undefined
>;
@property({ attribute: false }) @property({ attribute: false })
accessor updateContext!: (context: Partial<AIChatInputContext>) => void; accessor updateContext!: (context: Partial<AIChatInputContext>) => void;
@@ -608,7 +610,7 @@ export class AIChatInput extends SignalWatcher(
// optimistic update messages // optimistic update messages
await this._preUpdateMessages(userInput, attachments); await this._preUpdateMessages(userInput, attachments);
const sessionId = (await this.createSession())?.id; const sessionId = (await this.createSession())?.sessionId;
let contexts = await this._getMatchedContexts(); let contexts = await this._getMatchedContexts();
if (abortController.signal.aborted) { if (abortController.signal.aborted) {
return; return;
@@ -694,7 +696,7 @@ export class AIChatInput extends SignalWatcher(
}; };
private readonly _postUpdateMessages = async () => { private readonly _postUpdateMessages = async () => {
const sessionId = this.session?.id; const sessionId = this.session?.sessionId;
if (!sessionId || !AIProvider.histories) return; if (!sessionId || !AIProvider.histories) return;
const { messages } = this.chatContextValue; const { messages } = this.chatContextValue;
@@ -703,7 +705,7 @@ export class AIChatInput extends SignalWatcher(
const historyIds = await AIProvider.histories.ids( const historyIds = await AIProvider.histories.ids(
this.workspaceId, this.workspaceId,
this.docId, this.docId,
{ sessionId } { sessionId, withMessages: true }
); );
if (!historyIds || !historyIds[0]) return; if (!historyIds || !historyIds[0]) return;
last.id = historyIds[0].messages.at(-1)?.id ?? ''; last.id = historyIds[0].messages.at(-1)?.id ?? '';
@@ -1,4 +1,4 @@
import type { CopilotSessionType } from '@affine/graphql'; import type { CopilotChatHistoryFragment } from '@affine/graphql';
import { import {
menu, menu,
popMenu, popMenu,
@@ -49,7 +49,7 @@ export class ChatInputPreference extends SignalWatcher(
`; `;
@property({ attribute: false }) @property({ attribute: false })
accessor session!: CopilotSessionType | null | undefined; accessor session!: CopilotChatHistoryFragment | null | undefined;
@property({ attribute: false }) @property({ attribute: false })
accessor onModelChange: ((modelId: string) => void) | undefined; accessor onModelChange: ((modelId: string) => void) | undefined;
@@ -1,4 +1,4 @@
import type { CopilotSessionType } from '@affine/graphql'; import type { CopilotChatHistoryFragment } from '@affine/graphql';
import { WithDisposable } from '@blocksuite/affine/global/lit'; import { WithDisposable } from '@blocksuite/affine/global/lit';
import { import {
DocModeProvider, DocModeProvider,
@@ -171,10 +171,12 @@ export class AIChatMessages extends WithDisposable(ShadowlessElement) {
accessor chatContextValue!: ChatContextValue; accessor chatContextValue!: ChatContextValue;
@property({ attribute: false }) @property({ attribute: false })
accessor session!: CopilotSessionType | null | undefined; accessor session!: CopilotChatHistoryFragment | null | undefined;
@property({ attribute: false }) @property({ attribute: false })
accessor createSession!: () => Promise<CopilotSessionType | undefined>; accessor createSession!: () => Promise<
CopilotChatHistoryFragment | undefined
>;
@property({ attribute: false }) @property({ attribute: false })
accessor updateContext!: (context: Partial<ChatContextValue>) => void; accessor updateContext!: (context: Partial<ChatContextValue>) => void;
@@ -418,7 +420,7 @@ export class AIChatMessages extends WithDisposable(ShadowlessElement) {
retry = async () => { retry = async () => {
try { try {
const sessionId = (await this.createSession())?.id; const sessionId = (await this.createSession())?.sessionId;
if (!sessionId) return; if (!sessionId) return;
if (!AIProvider.actions.chat) return; if (!AIProvider.actions.chat) return;
@@ -1,4 +1,4 @@
import type { CopilotSessionType } from '@affine/graphql'; import type { CopilotChatHistoryFragment } from '@affine/graphql';
import { createLitPortal } from '@blocksuite/affine/components/portal'; import { createLitPortal } from '@blocksuite/affine/components/portal';
import { WithDisposable } from '@blocksuite/affine/global/lit'; import { WithDisposable } from '@blocksuite/affine/global/lit';
import type { NotificationService } from '@blocksuite/affine/shared/services'; import type { NotificationService } from '@blocksuite/affine/shared/services';
@@ -18,7 +18,7 @@ import type { DocDisplayConfig } from '../ai-chat-chips';
export class AIChatToolbar extends WithDisposable(ShadowlessElement) { export class AIChatToolbar extends WithDisposable(ShadowlessElement) {
@property({ attribute: false }) @property({ attribute: false })
accessor session!: CopilotSessionType | null | undefined; accessor session!: CopilotChatHistoryFragment | null | undefined;
@property({ attribute: false }) @property({ attribute: false })
accessor workspaceId!: string; accessor workspaceId!: string;
@@ -132,7 +132,7 @@ export class AIChatToolbar extends WithDisposable(ShadowlessElement) {
}; };
private readonly onSessionClick = async (sessionId: string) => { private readonly onSessionClick = async (sessionId: string) => {
if (this.session?.id === sessionId) { if (this.session?.sessionId === sessionId) {
this.notification?.toast('You are already in this chat'); this.notification?.toast('You are already in this chat');
return; return;
} }
@@ -143,7 +143,7 @@ export class AIChatToolbar extends WithDisposable(ShadowlessElement) {
}; };
private readonly onDocClick = async (docId: string, sessionId: string) => { private readonly onDocClick = async (docId: string, sessionId: string) => {
if (this.docId === docId && this.session?.id === sessionId) { if (this.docId === docId && this.session?.sessionId === sessionId) {
this.notification?.toast('You are already in this chat'); this.notification?.toast('You are already in this chat');
return; return;
} }
@@ -1,4 +1,4 @@
import type { CopilotSessionType } from '@affine/graphql'; import type { CopilotChatHistoryFragment } from '@affine/graphql';
import { WithDisposable } from '@blocksuite/affine/global/lit'; import { WithDisposable } from '@blocksuite/affine/global/lit';
import { type NotificationService } from '@blocksuite/affine/shared/services'; import { type NotificationService } from '@blocksuite/affine/shared/services';
import { unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme'; import { unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
@@ -15,7 +15,7 @@ export class AIHistoryClear extends WithDisposable(ShadowlessElement) {
accessor chatContextValue!: ChatContextValue; accessor chatContextValue!: ChatContextValue;
@property({ attribute: false }) @property({ attribute: false })
accessor session!: CopilotSessionType | null | undefined; accessor session!: CopilotChatHistoryFragment | null | undefined;
@property({ attribute: false }) @property({ attribute: false })
accessor notification: NotificationService | null | undefined; accessor notification: NotificationService | null | undefined;
@@ -50,7 +50,7 @@ export class AIHistoryClear extends WithDisposable(ShadowlessElement) {
if (this._isHistoryClearDisabled || !this.session) { if (this._isHistoryClearDisabled || !this.session) {
return; return;
} }
const sessionId = this.session.id; const sessionId = this.session.sessionId;
try { try {
const confirm = this.notification const confirm = this.notification
? await this.notification.confirm({ ? await this.notification.confirm({
@@ -1,4 +1,4 @@
import type { CopilotSessionType } from '@affine/graphql'; import type { CopilotChatHistoryFragment } from '@affine/graphql';
import type { ImageSelection } from '@blocksuite/affine/shared/selection'; import type { ImageSelection } from '@blocksuite/affine/shared/selection';
import { NotificationProvider } from '@blocksuite/affine/shared/services'; import { NotificationProvider } from '@blocksuite/affine/shared/services';
import type { import type {
@@ -82,7 +82,7 @@ export class ChatActionList extends LitElement {
accessor content: string = ''; accessor content: string = '';
@property({ attribute: false }) @property({ attribute: false })
accessor session!: CopilotSessionType | null | undefined; accessor session!: CopilotChatHistoryFragment | null | undefined;
@property({ attribute: false }) @property({ attribute: false })
accessor messageId: string | undefined = undefined; accessor messageId: string | undefined = undefined;
@@ -139,7 +139,7 @@ export class ChatActionList extends LitElement {
blocks: this._currentBlockSelections, blocks: this._currentBlockSelections,
images: this._currentImageSelections, images: this._currentImageSelections,
}; };
const sessionId = this.session?.id; const sessionId = this.session?.sessionId;
const success = await action.handler( const success = await action.handler(
host, host,
content, content,
@@ -1,4 +1,4 @@
import type { CopilotSessionType } from '@affine/graphql'; import type { CopilotChatHistoryFragment } from '@affine/graphql';
import { Tooltip } from '@blocksuite/affine/components/toolbar'; import { Tooltip } from '@blocksuite/affine/components/toolbar';
import { WithDisposable } from '@blocksuite/affine/global/lit'; import { WithDisposable } from '@blocksuite/affine/global/lit';
import { noop } from '@blocksuite/affine/global/utils'; import { noop } from '@blocksuite/affine/global/utils';
@@ -111,7 +111,7 @@ export class ChatCopyMore extends WithDisposable(LitElement) {
accessor actions: ChatAction[] = []; accessor actions: ChatAction[] = [];
@property({ attribute: false }) @property({ attribute: false })
accessor session!: CopilotSessionType | null | undefined; accessor session!: CopilotChatHistoryFragment | null | undefined;
@property({ attribute: false }) @property({ attribute: false })
accessor content!: string; accessor content!: string;
@@ -224,7 +224,7 @@ export class ChatCopyMore extends WithDisposable(LitElement) {
}; };
return html`<div return html`<div
@click=${async () => { @click=${async () => {
const sessionId = this.session?.id; const sessionId = this.session?.sessionId;
const success = await action.handler( const success = await action.handler(
host, host,
content, content,
@@ -1,5 +1,8 @@
import type { FeatureFlagService } from '@affine/core/modules/feature-flag'; import type { FeatureFlagService } from '@affine/core/modules/feature-flag';
import type { ContextEmbedStatus, CopilotSessionType } from '@affine/graphql'; import type {
ContextEmbedStatus,
CopilotChatHistoryFragment,
} from '@affine/graphql';
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit'; import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
import { NotificationProvider } from '@blocksuite/affine/shared/services'; import { NotificationProvider } from '@blocksuite/affine/shared/services';
import { unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme'; import { unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
@@ -130,7 +133,7 @@ export class PlaygroundChat extends SignalWatcher(
accessor doc!: Store; accessor doc!: Store;
@property({ attribute: false }) @property({ attribute: false })
accessor session!: CopilotSessionType | null | undefined; accessor session!: CopilotChatHistoryFragment | null | undefined;
@property({ attribute: false }) @property({ attribute: false })
accessor networkSearchConfig!: AINetworkSearchConfig; accessor networkSearchConfig!: AINetworkSearchConfig;
@@ -194,7 +197,7 @@ export class PlaygroundChat extends SignalWatcher(
const currentRequest = ++this._updateHistoryCounter; const currentRequest = ++this._updateHistoryCounter;
const sessionId = this.session?.id; const sessionId = this.session?.sessionId;
const [histories, actions] = await Promise.all([ const [histories, actions] = await Promise.all([
sessionId sessionId
? AIProvider.histories.chats( ? AIProvider.histories.chats(
@@ -1,5 +1,5 @@
import type { FeatureFlagService } from '@affine/core/modules/feature-flag'; import type { FeatureFlagService } from '@affine/core/modules/feature-flag';
import type { CopilotSessionType } from '@affine/graphql'; import type { CopilotChatHistoryFragment } from '@affine/graphql';
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit'; import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
import type { EditorHost } from '@blocksuite/affine/std'; import type { EditorHost } from '@blocksuite/affine/std';
import { ShadowlessElement } from '@blocksuite/affine/std'; import { ShadowlessElement } from '@blocksuite/affine/std';
@@ -84,7 +84,7 @@ export class PlaygroundContent extends SignalWatcher(
accessor affineFeatureFlagService!: FeatureFlagService; accessor affineFeatureFlagService!: FeatureFlagService;
@state() @state()
accessor sessions: CopilotSessionType[] = []; accessor sessions: CopilotChatHistoryFragment[] = [];
@state() @state()
accessor sharedInputValue: string = ''; accessor sharedInputValue: string = '';
@@ -118,14 +118,14 @@ export class PlaygroundContent extends SignalWatcher(
} }
} }
} else { } else {
this.rootSessionId = rootSession.id; this.rootSessionId = rootSession.sessionId;
const childSessions = sessions.filter( const childSessions = sessions.filter(
session => session.parentSessionId === rootSession.id session => session.parentSessionId === rootSession.sessionId
); );
if (childSessions.length > 0) { if (childSessions.length > 0) {
this.sessions = childSessions; this.sessions = childSessions;
} else { } else {
const forkSession = await this.forkSession(rootSession.id); const forkSession = await this.forkSession(rootSession.sessionId);
if (forkSession) { if (forkSession) {
this.sessions = [forkSession]; this.sessions = [forkSession];
} }
@@ -321,7 +321,7 @@ export class PlaygroundContent extends SignalWatcher(
<div class="playground-content"> <div class="playground-content">
${repeat( ${repeat(
this.sessions, this.sessions,
session => session.id, session => session.sessionId,
session => html` session => html`
<div class="playground-chat-item"> <div class="playground-chat-item">
<playground-chat <playground-chat
@@ -1,6 +1,9 @@
import type { WorkspaceDialogService } from '@affine/core/modules/dialogs'; import type { WorkspaceDialogService } from '@affine/core/modules/dialogs';
import type { FeatureFlagService } from '@affine/core/modules/feature-flag'; import type { FeatureFlagService } from '@affine/core/modules/feature-flag';
import type { ContextEmbedStatus, CopilotSessionType } from '@affine/graphql'; import type {
ContextEmbedStatus,
CopilotChatHistoryFragment,
} from '@affine/graphql';
import { import {
CanvasElementType, CanvasElementType,
EdgelessCRUDIdentifier, EdgelessCRUDIdentifier,
@@ -216,7 +219,7 @@ export class AIChatBlockPeekView extends LitElement {
} }
// If there is no session id or chat messages, do not create a new chat block // If there is no session id or chat messages, do not create a new chat block
const forkSessionId = this.forkSession?.id; const forkSessionId = this.forkSession?.sessionId;
if (!forkSessionId || !this.chatContext.messages.length) { if (!forkSessionId || !this.chatContext.messages.length) {
return; return;
} }
@@ -284,7 +287,7 @@ export class AIChatBlockPeekView extends LitElement {
* Update the current chat messages with the new message * Update the current chat messages with the new message
*/ */
updateChatBlockMessages = async () => { updateChatBlockMessages = async () => {
const forkSessionId = this.forkSession?.id; const forkSessionId = this.forkSession?.sessionId;
if (!this._forkBlockId || !forkSessionId) { if (!this._forkBlockId || !forkSessionId) {
return; return;
} }
@@ -360,7 +363,7 @@ export class AIChatBlockPeekView extends LitElement {
*/ */
retry = async () => { retry = async () => {
try { try {
const forkSessionId = this.forkSession?.id; const forkSessionId = this.forkSession?.sessionId;
if (!this._forkBlockId || !forkSessionId) return; if (!this._forkBlockId || !forkSessionId) return;
if (!AIProvider.actions.chat) return; if (!AIProvider.actions.chat) return;
@@ -656,10 +659,10 @@ export class AIChatBlockPeekView extends LitElement {
accessor embeddingProgress: [number, number] = [0, 0]; accessor embeddingProgress: [number, number] = [0, 0];
@state() @state()
accessor session: CopilotSessionType | null | undefined; accessor session: CopilotChatHistoryFragment | null | undefined;
@state() @state()
accessor forkSession: CopilotSessionType | null | undefined; accessor forkSession: CopilotChatHistoryFragment | null | undefined;
} }
declare global { declare global {
@@ -19,6 +19,7 @@ import {
listContextObjectQuery, listContextObjectQuery,
listContextQuery, listContextQuery,
matchContextQuery, matchContextQuery,
type PaginationInput,
type QueryOptions, type QueryOptions,
type QueryResponse, type QueryResponse,
removeContextCategoryMutation, removeContextCategoryMutation,
@@ -152,7 +153,7 @@ export class CopilotClient {
query: getCopilotSessionQuery, query: getCopilotSessionQuery,
variables: { sessionId, workspaceId }, variables: { sessionId, workspaceId },
}); });
return res.currentUser?.copilot?.session; return res.currentUser?.copilot?.chats?.edges?.[0]?.node;
} catch (err) { } catch (err) {
throw resolveError(err); throw resolveError(err);
} }
@@ -160,6 +161,7 @@ export class CopilotClient {
async getSessions( async getSessions(
workspaceId: string, workspaceId: string,
pagination: PaginationInput,
docId?: string, docId?: string,
options?: RequestOptions< options?: RequestOptions<
typeof getCopilotSessionsQuery typeof getCopilotSessionsQuery
@@ -170,11 +172,12 @@ export class CopilotClient {
query: getCopilotSessionsQuery, query: getCopilotSessionsQuery,
variables: { variables: {
workspaceId, workspaceId,
pagination,
docId, docId,
options, options,
}, },
}); });
return res.currentUser?.copilot?.sessions; return res.currentUser?.copilot?.chats.edges.map(e => e.node);
} catch (err) { } catch (err) {
throw resolveError(err); throw resolveError(err);
} }
@@ -189,7 +192,7 @@ export class CopilotClient {
limit, limit,
}, },
}); });
return res.currentUser?.copilot?.histories; return res.currentUser?.copilot?.chats.edges.map(e => e.node);
} catch (err) { } catch (err) {
throw resolveError(err); throw resolveError(err);
} }
@@ -197,6 +200,7 @@ export class CopilotClient {
async getHistories( async getHistories(
workspaceId: string, workspaceId: string,
pagination: PaginationInput,
docId?: string, docId?: string,
options?: RequestOptions< options?: RequestOptions<
typeof getCopilotHistoriesQuery typeof getCopilotHistoriesQuery
@@ -207,12 +211,13 @@ export class CopilotClient {
query: getCopilotHistoriesQuery, query: getCopilotHistoriesQuery,
variables: { variables: {
workspaceId, workspaceId,
pagination,
docId, docId,
options, options,
}, },
}); });
return res.currentUser?.copilot?.histories; return res.currentUser?.copilot?.chats.edges.map(e => e.node);
} catch (err) { } catch (err) {
throw resolveError(err); throw resolveError(err);
} }
@@ -220,9 +225,10 @@ export class CopilotClient {
async getHistoryIds( async getHistoryIds(
workspaceId: string, workspaceId: string,
pagination: PaginationInput,
docId?: string, docId?: string,
options?: RequestOptions< options?: RequestOptions<
typeof getCopilotHistoriesQuery typeof getCopilotHistoryIdsQuery
>['variables']['options'] >['variables']['options']
) { ) {
try { try {
@@ -230,12 +236,13 @@ export class CopilotClient {
query: getCopilotHistoryIdsQuery, query: getCopilotHistoryIdsQuery,
variables: { variables: {
workspaceId, workspaceId,
pagination,
docId, docId,
options, options,
}, },
}); });
return res.currentUser?.copilot?.histories; return res.currentUser?.copilot?.chats.edges.map(e => e.node);
} catch (err) { } catch (err) {
throw resolveError(err); throw resolveError(err);
} }
@@ -586,7 +586,7 @@ Could you make a new website based on these notes and send back just the html fi
docId?: string, docId?: string,
options?: QueryChatSessionsInput options?: QueryChatSessionsInput
) => { ) => {
return client.getSessions(workspaceId, docId, options); return client.getSessions(workspaceId, {}, docId, options);
}, },
getRecentSessions: async (workspaceId: string, limit?: number) => { getRecentSessions: async (workspaceId: string, limit?: number) => {
return client.getRecentSessions(workspaceId, limit); return client.getRecentSessions(workspaceId, limit);
@@ -744,9 +744,10 @@ Could you make a new website based on these notes and send back just the html fi
): Promise<BlockSuitePresets.AIHistory[]> => { ): Promise<BlockSuitePresets.AIHistory[]> => {
// @ts-expect-error - 'action' is missing in server impl // @ts-expect-error - 'action' is missing in server impl
return ( return (
(await client.getHistories(workspaceId, docId, { (await client.getHistories(workspaceId, {}, docId, {
action: true, action: true,
withPrompt: true, withPrompt: true,
withMessages: true,
})) ?? [] })) ?? []
); );
}, },
@@ -757,8 +758,9 @@ Could you make a new website based on these notes and send back just the html fi
): Promise<BlockSuitePresets.AIHistory[]> => { ): Promise<BlockSuitePresets.AIHistory[]> => {
// @ts-expect-error - 'action' is missing in server impl // @ts-expect-error - 'action' is missing in server impl
return ( return (
(await client.getHistories(workspaceId, docId, { (await client.getHistories(workspaceId, {}, docId, {
sessionId, sessionId,
withMessages: true,
})) ?? [] })) ?? []
); );
}, },
@@ -776,8 +778,8 @@ Could you make a new website based on these notes and send back just the html fi
typeof getCopilotHistoriesQuery typeof getCopilotHistoriesQuery
>['variables']['options'] >['variables']['options']
): Promise<BlockSuitePresets.AIHistoryIds[]> => { ): Promise<BlockSuitePresets.AIHistoryIds[]> => {
// @ts-expect-error - 'role' is missing type in server impl // @ts-expect-error - 'action' is missing in server impl
return await client.getHistoryIds(workspaceId, docId, options); return await client.getHistoryIds(workspaceId, {}, docId, options);
}, },
}); });
@@ -98,11 +98,14 @@ export const Component = () => {
await createSession({ pinned }); await createSession({ pinned });
} else { } else {
await client.updateSession({ await client.updateSession({
sessionId: currentSession.id, sessionId: currentSession.sessionId,
pinned, pinned,
}); });
// retrieve the latest session and update the state // retrieve the latest session and update the state
const session = await client.getSession(workspaceId, currentSession.id); const session = await client.getSession(
workspaceId,
currentSession.sessionId
);
setCurrentSession(session); setCurrentSession(session);
} }
} finally { } finally {