mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-07 01:09:54 +08:00
feat(server): tag and collection record for context (#10926)
fix CLOUD-174
This commit is contained in:
@@ -40,6 +40,8 @@ import { CopilotStorage } from '../storage';
|
|||||||
import { CopilotContextDocJob } from './job';
|
import { CopilotContextDocJob } from './job';
|
||||||
import { CopilotContextService } from './service';
|
import { CopilotContextService } from './service';
|
||||||
import {
|
import {
|
||||||
|
ContextCategories,
|
||||||
|
ContextCategory,
|
||||||
ContextDoc,
|
ContextDoc,
|
||||||
ContextEmbedStatus,
|
ContextEmbedStatus,
|
||||||
type ContextFile,
|
type ContextFile,
|
||||||
@@ -49,6 +51,18 @@ import {
|
|||||||
} from './types';
|
} from './types';
|
||||||
import { readStream } from './utils';
|
import { readStream } from './utils';
|
||||||
|
|
||||||
|
@InputType()
|
||||||
|
class AddRemoveContextCategoryInput {
|
||||||
|
@Field(() => String)
|
||||||
|
contextId!: string;
|
||||||
|
|
||||||
|
@Field(() => ContextCategories)
|
||||||
|
type!: ContextCategories;
|
||||||
|
|
||||||
|
@Field(() => String)
|
||||||
|
categoryId!: string;
|
||||||
|
}
|
||||||
|
|
||||||
@InputType()
|
@InputType()
|
||||||
class AddContextDocInput {
|
class AddContextDocInput {
|
||||||
@Field(() => String)
|
@Field(() => String)
|
||||||
@@ -94,6 +108,20 @@ export class CopilotContextType {
|
|||||||
workspaceId!: string;
|
workspaceId!: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registerEnumType(ContextCategories, { name: 'ContextCategories' });
|
||||||
|
|
||||||
|
@ObjectType()
|
||||||
|
class CopilotContextCategory implements ContextCategory {
|
||||||
|
@Field(() => ID)
|
||||||
|
id!: string;
|
||||||
|
|
||||||
|
@Field(() => ContextCategories)
|
||||||
|
type!: ContextCategories;
|
||||||
|
|
||||||
|
@Field(() => SafeIntResolver)
|
||||||
|
createdAt!: number;
|
||||||
|
}
|
||||||
|
|
||||||
registerEnumType(ContextEmbedStatus, { name: 'ContextEmbedStatus' });
|
registerEnumType(ContextEmbedStatus, { name: 'ContextEmbedStatus' });
|
||||||
|
|
||||||
@ObjectType()
|
@ObjectType()
|
||||||
@@ -335,6 +363,59 @@ export class CopilotContextResolver {
|
|||||||
return session.listDocs();
|
return session.listDocs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Mutation(() => CopilotContextCategory, {
|
||||||
|
description: 'add a category to context',
|
||||||
|
})
|
||||||
|
@CallMetric('ai', 'context_category_add')
|
||||||
|
async addContextCategory(
|
||||||
|
@Args({ name: 'options', type: () => AddRemoveContextCategoryInput })
|
||||||
|
options: AddRemoveContextCategoryInput
|
||||||
|
) {
|
||||||
|
const lockFlag = `${COPILOT_LOCKER}:context:${options.contextId}`;
|
||||||
|
await using lock = await this.mutex.acquire(lockFlag);
|
||||||
|
if (!lock) {
|
||||||
|
return new TooManyRequest('Server is busy');
|
||||||
|
}
|
||||||
|
const session = await this.context.get(options.contextId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await session.addCategoryRecord(options.type, options.categoryId);
|
||||||
|
} catch (e: any) {
|
||||||
|
throw new CopilotFailedToModifyContext({
|
||||||
|
contextId: options.contextId,
|
||||||
|
message: e.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Mutation(() => Boolean, {
|
||||||
|
description: 'remove a category from context',
|
||||||
|
})
|
||||||
|
@CallMetric('ai', 'context_category_remove')
|
||||||
|
async removeContextCategory(
|
||||||
|
@Args({ name: 'options', type: () => AddRemoveContextCategoryInput })
|
||||||
|
options: AddRemoveContextCategoryInput
|
||||||
|
) {
|
||||||
|
const lockFlag = `${COPILOT_LOCKER}:context:${options.contextId}`;
|
||||||
|
await using lock = await this.mutex.acquire(lockFlag);
|
||||||
|
if (!lock) {
|
||||||
|
return new TooManyRequest('Server is busy');
|
||||||
|
}
|
||||||
|
const session = await this.context.get(options.contextId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await session.removeCategoryRecord(
|
||||||
|
options.type,
|
||||||
|
options.categoryId
|
||||||
|
);
|
||||||
|
} catch (e: any) {
|
||||||
|
throw new CopilotFailedToModifyContext({
|
||||||
|
contextId: options.contextId,
|
||||||
|
message: e.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Mutation(() => CopilotContextDoc, {
|
@Mutation(() => CopilotContextDoc, {
|
||||||
description: 'add a doc to context',
|
description: 'add a doc to context',
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
ContextEmbedStatus,
|
ContextEmbedStatus,
|
||||||
ContextFile,
|
ContextFile,
|
||||||
EmbeddingClient,
|
EmbeddingClient,
|
||||||
|
MinimalContextConfigSchema,
|
||||||
} from './types';
|
} from './types';
|
||||||
import { checkEmbeddingAvailable } from './utils';
|
import { checkEmbeddingAvailable } from './utils';
|
||||||
|
|
||||||
@@ -128,7 +129,12 @@ export class CopilotContextService implements OnModuleInit {
|
|||||||
const context = await this.db.aiContext.create({
|
const context = await this.db.aiContext.create({
|
||||||
data: {
|
data: {
|
||||||
sessionId,
|
sessionId,
|
||||||
config: { workspaceId: session.workspaceId, docs: [], files: [] },
|
config: {
|
||||||
|
workspaceId: session.workspaceId,
|
||||||
|
docs: [],
|
||||||
|
files: [],
|
||||||
|
categories: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -149,7 +155,19 @@ export class CopilotContextService implements OnModuleInit {
|
|||||||
});
|
});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
const config = ContextConfigSchema.safeParse(ret.config);
|
const config = ContextConfigSchema.safeParse(ret.config);
|
||||||
if (config.success) return this.cacheSession(id, config.data);
|
if (config.success) {
|
||||||
|
return this.cacheSession(id, config.data);
|
||||||
|
}
|
||||||
|
const minimalConfig = MinimalContextConfigSchema.safeParse(ret.config);
|
||||||
|
if (minimalConfig.success) {
|
||||||
|
// fulfill the missing fields
|
||||||
|
return this.cacheSession(id, {
|
||||||
|
...minimalConfig.data,
|
||||||
|
docs: [],
|
||||||
|
files: [],
|
||||||
|
categories: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw new CopilotInvalidContext({ contextId: id });
|
throw new CopilotInvalidContext({ contextId: id });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { nanoid } from 'nanoid';
|
|||||||
import { PrismaTransaction } from '../../../base';
|
import { PrismaTransaction } from '../../../base';
|
||||||
import {
|
import {
|
||||||
ChunkSimilarity,
|
ChunkSimilarity,
|
||||||
|
ContextCategories,
|
||||||
ContextConfig,
|
ContextConfig,
|
||||||
ContextDoc,
|
ContextDoc,
|
||||||
ContextEmbedStatus,
|
ContextEmbedStatus,
|
||||||
@@ -49,6 +50,30 @@ export class ContextSession implements AsyncDisposable {
|
|||||||
) as ContextList;
|
) as ContextList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async addCategoryRecord(type: ContextCategories, id: string) {
|
||||||
|
const category = this.config.categories.find(
|
||||||
|
c => c.type === type && c.id === id
|
||||||
|
);
|
||||||
|
if (category) {
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
const record = { id, type, createdAt: Date.now() };
|
||||||
|
this.config.categories.push(record);
|
||||||
|
await this.save();
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeCategoryRecord(type: ContextCategories, id: string) {
|
||||||
|
const index = this.config.categories.findIndex(
|
||||||
|
c => c.type === type && c.id === id
|
||||||
|
);
|
||||||
|
if (index >= 0) {
|
||||||
|
this.config.categories.splice(index, 1);
|
||||||
|
await this.save();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
async addDocRecord(docId: string): Promise<ContextDoc> {
|
async addDocRecord(docId: string): Promise<ContextDoc> {
|
||||||
const doc = this.config.docs.find(f => f.id === docId);
|
const doc = this.config.docs.find(f => f.id === docId);
|
||||||
if (doc) {
|
if (doc) {
|
||||||
@@ -65,9 +90,8 @@ export class ContextSession implements AsyncDisposable {
|
|||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
this.config.docs.splice(index, 1);
|
this.config.docs.splice(index, 1);
|
||||||
await this.save();
|
await this.save();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async addFile(blobId: string, name: string): Promise<ContextFile> {
|
async addFile(blobId: string, name: string): Promise<ContextFile> {
|
||||||
|
|||||||
@@ -32,6 +32,11 @@ export enum ContextEmbedStatus {
|
|||||||
failed = 'failed',
|
failed = 'failed',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum ContextCategories {
|
||||||
|
Tag = 'tag',
|
||||||
|
Collection = 'collection',
|
||||||
|
}
|
||||||
|
|
||||||
export const ContextConfigSchema = z.object({
|
export const ContextConfigSchema = z.object({
|
||||||
workspaceId: z.string(),
|
workspaceId: z.string(),
|
||||||
files: z
|
files: z
|
||||||
@@ -64,9 +69,23 @@ export const ContextConfigSchema = z.object({
|
|||||||
createdAt: z.number(),
|
createdAt: z.number(),
|
||||||
})
|
})
|
||||||
.array(),
|
.array(),
|
||||||
|
categories: z
|
||||||
|
.object({
|
||||||
|
id: z.string(),
|
||||||
|
type: z.enum([ContextCategories.Tag, ContextCategories.Collection]),
|
||||||
|
createdAt: z.number(),
|
||||||
|
})
|
||||||
|
.array(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const MinimalContextConfigSchema = ContextConfigSchema.pick({
|
||||||
|
workspaceId: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
export type ContextConfig = z.infer<typeof ContextConfigSchema>;
|
export type ContextConfig = z.infer<typeof ContextConfigSchema>;
|
||||||
|
export type ContextCategory = z.infer<
|
||||||
|
typeof ContextConfigSchema
|
||||||
|
>['categories'][number];
|
||||||
export type ContextDoc = z.infer<typeof ContextConfigSchema>['docs'][number];
|
export type ContextDoc = z.infer<typeof ContextConfigSchema>['docs'][number];
|
||||||
export type ContextFile = z.infer<typeof ContextConfigSchema>['files'][number];
|
export type ContextFile = z.infer<typeof ContextConfigSchema>['files'][number];
|
||||||
export type ContextListItem = ContextDoc | ContextFile;
|
export type ContextListItem = ContextDoc | ContextFile;
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ input AddContextFileInput {
|
|||||||
contextId: String!
|
contextId: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input AddRemoveContextCategoryInput {
|
||||||
|
categoryId: String!
|
||||||
|
contextId: String!
|
||||||
|
type: ContextCategories!
|
||||||
|
}
|
||||||
|
|
||||||
type AlreadyInSpaceDataType {
|
type AlreadyInSpaceDataType {
|
||||||
spaceId: String!
|
spaceId: String!
|
||||||
}
|
}
|
||||||
@@ -35,6 +41,11 @@ type ChatMessage {
|
|||||||
role: String!
|
role: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ContextCategories {
|
||||||
|
Collection
|
||||||
|
Tag
|
||||||
|
}
|
||||||
|
|
||||||
enum ContextEmbedStatus {
|
enum ContextEmbedStatus {
|
||||||
failed
|
failed
|
||||||
finished
|
finished
|
||||||
@@ -92,6 +103,12 @@ type CopilotContext {
|
|||||||
workspaceId: String!
|
workspaceId: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CopilotContextCategory {
|
||||||
|
createdAt: SafeInt!
|
||||||
|
id: ID!
|
||||||
|
type: ContextCategories!
|
||||||
|
}
|
||||||
|
|
||||||
type CopilotContextDoc {
|
type CopilotContextDoc {
|
||||||
createdAt: SafeInt!
|
createdAt: SafeInt!
|
||||||
id: ID!
|
id: ID!
|
||||||
@@ -803,6 +820,9 @@ type Mutation {
|
|||||||
acceptInviteById(inviteId: String!, sendAcceptMail: Boolean, workspaceId: String!): Boolean!
|
acceptInviteById(inviteId: String!, sendAcceptMail: Boolean, workspaceId: String!): Boolean!
|
||||||
activateLicense(license: String!, workspaceId: String!): License!
|
activateLicense(license: String!, workspaceId: String!): License!
|
||||||
|
|
||||||
|
"""add a category to context"""
|
||||||
|
addContextCategory(options: AddRemoveContextCategoryInput!): CopilotContextCategory!
|
||||||
|
|
||||||
"""add a doc to context"""
|
"""add a doc to context"""
|
||||||
addContextDoc(options: AddContextDocInput!): CopilotContextDoc!
|
addContextDoc(options: AddContextDocInput!): CopilotContextDoc!
|
||||||
|
|
||||||
@@ -887,6 +907,9 @@ type Mutation {
|
|||||||
"""Remove user avatar"""
|
"""Remove user avatar"""
|
||||||
removeAvatar: RemoveAvatar!
|
removeAvatar: RemoveAvatar!
|
||||||
|
|
||||||
|
"""remove a category from context"""
|
||||||
|
removeContextCategory(options: AddRemoveContextCategoryInput!): Boolean!
|
||||||
|
|
||||||
"""remove a doc from context"""
|
"""remove a doc from context"""
|
||||||
removeContextDoc(options: RemoveContextDocInput!): Boolean!
|
removeContextDoc(options: RemoveContextDocInput!): Boolean!
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
mutation addContextCategory($options: AddRemoveContextCategoryInput!) {
|
||||||
|
addContextCategory(options: $options) {
|
||||||
|
id
|
||||||
|
createdAt
|
||||||
|
type
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
mutation removeContextCategory($options: AddRemoveContextCategoryInput!) {
|
||||||
|
removeContextCategory(options: $options)
|
||||||
|
}
|
||||||
@@ -134,6 +134,26 @@ export const changePasswordMutation = {
|
|||||||
}`,
|
}`,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const addContextCategoryMutation = {
|
||||||
|
id: 'addContextCategoryMutation' as const,
|
||||||
|
op: 'addContextCategory',
|
||||||
|
query: `mutation addContextCategory($options: AddRemoveContextCategoryInput!) {
|
||||||
|
addContextCategory(options: $options) {
|
||||||
|
id
|
||||||
|
createdAt
|
||||||
|
type
|
||||||
|
}
|
||||||
|
}`,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const removeContextCategoryMutation = {
|
||||||
|
id: 'removeContextCategoryMutation' as const,
|
||||||
|
op: 'removeContextCategory',
|
||||||
|
query: `mutation removeContextCategory($options: AddRemoveContextCategoryInput!) {
|
||||||
|
removeContextCategory(options: $options)
|
||||||
|
}`,
|
||||||
|
};
|
||||||
|
|
||||||
export const createCopilotContextMutation = {
|
export const createCopilotContextMutation = {
|
||||||
id: 'createCopilotContextMutation' as const,
|
id: 'createCopilotContextMutation' as const,
|
||||||
op: 'createCopilotContext',
|
op: 'createCopilotContext',
|
||||||
|
|||||||
@@ -47,6 +47,12 @@ export interface AddContextFileInput {
|
|||||||
contextId: Scalars['String']['input'];
|
contextId: Scalars['String']['input'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AddRemoveContextCategoryInput {
|
||||||
|
categoryId: Scalars['String']['input'];
|
||||||
|
contextId: Scalars['String']['input'];
|
||||||
|
type: ContextCategories;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AlreadyInSpaceDataType {
|
export interface AlreadyInSpaceDataType {
|
||||||
__typename?: 'AlreadyInSpaceDataType';
|
__typename?: 'AlreadyInSpaceDataType';
|
||||||
spaceId: Scalars['String']['output'];
|
spaceId: Scalars['String']['output'];
|
||||||
@@ -73,6 +79,11 @@ export interface ChatMessage {
|
|||||||
role: Scalars['String']['output'];
|
role: Scalars['String']['output'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum ContextCategories {
|
||||||
|
Collection = 'Collection',
|
||||||
|
Tag = 'Tag',
|
||||||
|
}
|
||||||
|
|
||||||
export enum ContextEmbedStatus {
|
export enum ContextEmbedStatus {
|
||||||
failed = 'failed',
|
failed = 'failed',
|
||||||
finished = 'finished',
|
finished = 'finished',
|
||||||
@@ -163,6 +174,13 @@ export interface CopilotContextMatchWorkspaceContextArgs {
|
|||||||
limit?: InputMaybe<Scalars['SafeInt']['input']>;
|
limit?: InputMaybe<Scalars['SafeInt']['input']>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CopilotContextCategory {
|
||||||
|
__typename?: 'CopilotContextCategory';
|
||||||
|
createdAt: Scalars['SafeInt']['output'];
|
||||||
|
id: Scalars['ID']['output'];
|
||||||
|
type: ContextCategories;
|
||||||
|
}
|
||||||
|
|
||||||
export interface CopilotContextDoc {
|
export interface CopilotContextDoc {
|
||||||
__typename?: 'CopilotContextDoc';
|
__typename?: 'CopilotContextDoc';
|
||||||
createdAt: Scalars['SafeInt']['output'];
|
createdAt: Scalars['SafeInt']['output'];
|
||||||
@@ -938,6 +956,8 @@ export interface Mutation {
|
|||||||
__typename?: 'Mutation';
|
__typename?: 'Mutation';
|
||||||
acceptInviteById: Scalars['Boolean']['output'];
|
acceptInviteById: Scalars['Boolean']['output'];
|
||||||
activateLicense: License;
|
activateLicense: License;
|
||||||
|
/** add a category to context */
|
||||||
|
addContextCategory: CopilotContextCategory;
|
||||||
/** add a doc to context */
|
/** add a doc to context */
|
||||||
addContextDoc: CopilotContextDoc;
|
addContextDoc: CopilotContextDoc;
|
||||||
/** add a file to context */
|
/** add a file to context */
|
||||||
@@ -1002,6 +1022,8 @@ export interface Mutation {
|
|||||||
releaseDeletedBlobs: Scalars['Boolean']['output'];
|
releaseDeletedBlobs: Scalars['Boolean']['output'];
|
||||||
/** Remove user avatar */
|
/** Remove user avatar */
|
||||||
removeAvatar: RemoveAvatar;
|
removeAvatar: RemoveAvatar;
|
||||||
|
/** remove a category from context */
|
||||||
|
removeContextCategory: Scalars['Boolean']['output'];
|
||||||
/** remove a doc from context */
|
/** remove a doc from context */
|
||||||
removeContextDoc: Scalars['Boolean']['output'];
|
removeContextDoc: Scalars['Boolean']['output'];
|
||||||
/** remove a file from context */
|
/** remove a file from context */
|
||||||
@@ -1054,6 +1076,10 @@ export interface MutationActivateLicenseArgs {
|
|||||||
workspaceId: Scalars['String']['input'];
|
workspaceId: Scalars['String']['input'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MutationAddContextCategoryArgs {
|
||||||
|
options: AddRemoveContextCategoryInput;
|
||||||
|
}
|
||||||
|
|
||||||
export interface MutationAddContextDocArgs {
|
export interface MutationAddContextDocArgs {
|
||||||
options: AddContextDocInput;
|
options: AddContextDocInput;
|
||||||
}
|
}
|
||||||
@@ -1240,6 +1266,10 @@ export interface MutationReleaseDeletedBlobsArgs {
|
|||||||
workspaceId: Scalars['String']['input'];
|
workspaceId: Scalars['String']['input'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MutationRemoveContextCategoryArgs {
|
||||||
|
options: AddRemoveContextCategoryInput;
|
||||||
|
}
|
||||||
|
|
||||||
export interface MutationRemoveContextDocArgs {
|
export interface MutationRemoveContextDocArgs {
|
||||||
options: RemoveContextDocInput;
|
options: RemoveContextDocInput;
|
||||||
}
|
}
|
||||||
@@ -2319,6 +2349,29 @@ export type ChangePasswordMutation = {
|
|||||||
changePassword: boolean;
|
changePassword: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type AddContextCategoryMutationVariables = Exact<{
|
||||||
|
options: AddRemoveContextCategoryInput;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export type AddContextCategoryMutation = {
|
||||||
|
__typename?: 'Mutation';
|
||||||
|
addContextCategory: {
|
||||||
|
__typename?: 'CopilotContextCategory';
|
||||||
|
id: string;
|
||||||
|
createdAt: number;
|
||||||
|
type: ContextCategories;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RemoveContextCategoryMutationVariables = Exact<{
|
||||||
|
options: AddRemoveContextCategoryInput;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export type RemoveContextCategoryMutation = {
|
||||||
|
__typename?: 'Mutation';
|
||||||
|
removeContextCategory: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
export type CreateCopilotContextMutationVariables = Exact<{
|
export type CreateCopilotContextMutationVariables = Exact<{
|
||||||
workspaceId: Scalars['String']['input'];
|
workspaceId: Scalars['String']['input'];
|
||||||
sessionId: Scalars['String']['input'];
|
sessionId: Scalars['String']['input'];
|
||||||
@@ -4308,6 +4361,16 @@ export type Mutations =
|
|||||||
variables: ChangePasswordMutationVariables;
|
variables: ChangePasswordMutationVariables;
|
||||||
response: ChangePasswordMutation;
|
response: ChangePasswordMutation;
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
name: 'addContextCategoryMutation';
|
||||||
|
variables: AddContextCategoryMutationVariables;
|
||||||
|
response: AddContextCategoryMutation;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
name: 'removeContextCategoryMutation';
|
||||||
|
variables: RemoveContextCategoryMutationVariables;
|
||||||
|
response: RemoveContextCategoryMutation;
|
||||||
|
}
|
||||||
| {
|
| {
|
||||||
name: 'createCopilotContextMutation';
|
name: 'createCopilotContextMutation';
|
||||||
variables: CreateCopilotContextMutationVariables;
|
variables: CreateCopilotContextMutationVariables;
|
||||||
|
|||||||
Reference in New Issue
Block a user