llzai's picture
Upload 1793 files
9853396 verified
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { graphqlRequest } from '@/gql/graphql';
import { useTranslation } from 'react-i18next';
import { toast } from 'sonner';
import { Model, ModelConnection, CreateModelInput, UpdateModelInput, modelConnectionSchema, modelSchema } from './schema';
const MODELS_QUERY = `
query GetModels(
$first: Int
$after: Cursor
$last: Int
$before: Cursor
$where: ModelWhereInput
$orderBy: ModelOrder
) {
models(first: $first, after: $after, last: $last, before: $before, where: $where, orderBy: $orderBy) {
edges {
node {
id
createdAt
updatedAt
developer
modelID
icon
type
name
group
modelCard {
reasoning {
supported
default
}
toolCall
temperature
modalities {
input
output
}
vision
cost {
input
output
cacheRead
cacheWrite
}
limit {
context
output
}
knowledge
releaseDate
lastUpdated
}
settings {
associations {
type
priority
disabled
channelModel {
channelId
modelId
}
channelRegex {
channelId
pattern
}
regex {
pattern
exclude {
channelNamePattern
channelIds
channelTags
}
}
modelId {
modelId
exclude {
channelNamePattern
channelIds
channelTags
}
}
channelTagsModel {
channelTags
modelId
}
channelTagsRegex {
channelTags
pattern
}
}
}
status
remark
associatedChannelCount
}
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
totalCount
}
}
`;
const CREATE_MODEL_MUTATION = `
mutation CreateModel($input: CreateModelInput!) {
createModel(input: $input) {
id
createdAt
updatedAt
developer
modelID
icon
type
name
group
modelCard {
reasoning {
supported
default
}
toolCall
temperature
modalities {
input
output
}
vision
cost {
input
output
cacheRead
cacheWrite
}
limit {
context
output
}
knowledge
releaseDate
lastUpdated
}
settings {
associations {
type
priority
disabled
channelModel {
channelId
modelId
}
channelRegex {
channelId
pattern
}
regex {
pattern
exclude {
channelNamePattern
channelIds
channelTags
}
}
modelId {
modelId
exclude {
channelNamePattern
channelIds
channelTags
}
}
}
}
status
remark
associatedChannelCount
}
}
`;
const BULK_CREATE_MODELS_MUTATION = `
mutation BulkCreateModels($inputs: [CreateModelInput!]!) {
bulkCreateModels(inputs: $inputs) {
id
createdAt
updatedAt
developer
modelID
icon
type
name
group
modelCard {
reasoning {
supported
default
}
toolCall
temperature
modalities {
input
output
}
vision
cost {
input
output
cacheRead
cacheWrite
}
limit {
context
output
}
knowledge
releaseDate
lastUpdated
}
settings {
associations {
type
priority
disabled
channelModel {
channelId
modelId
}
channelRegex {
channelId
pattern
}
regex {
pattern
exclude {
channelNamePattern
channelIds
channelTags
}
}
modelId {
modelId
exclude {
channelNamePattern
channelIds
channelTags
}
}
}
}
status
remark
associatedChannelCount
}
}
`;
const UPDATE_MODEL_MUTATION = `
mutation UpdateModel($id: ID!, $input: UpdateModelInput!) {
updateModel(id: $id, input: $input) {
id
createdAt
updatedAt
developer
modelID
icon
type
name
group
modelCard {
reasoning {
supported
default
}
toolCall
temperature
modalities {
input
output
}
vision
cost {
input
output
cacheRead
cacheWrite
}
limit {
context
output
}
knowledge
releaseDate
lastUpdated
}
settings {
associations {
type
priority
disabled
channelModel {
channelId
modelId
}
channelRegex {
channelId
pattern
}
regex {
pattern
exclude {
channelNamePattern
channelIds
channelTags
}
}
modelId {
modelId
exclude {
channelNamePattern
channelIds
channelTags
}
}
}
}
status
remark
associatedChannelCount
}
}
`;
const DELETE_MODEL_MUTATION = `
mutation DeleteModel($id: ID!) {
deleteModel(id: $id)
}
`;
const BULK_DISABLE_MODELS_MUTATION = `
mutation BulkDisableModels($ids: [ID!]!) {
bulkDisableModels(ids: $ids)
}
`;
const BULK_ENABLE_MODELS_MUTATION = `
mutation BulkEnableModels($ids: [ID!]!) {
bulkEnableModels(ids: $ids)
}
`;
const QUERY_UNASSOCIATED_CHANNELS = `
query QueryUnassociatedChannels {
queryUnassociatedChannels {
channel {
id
name
type
status
}
models
}
}
`;
interface QueryModelsArgs {
first?: number;
after?: string;
last?: number;
before?: string;
where?: Record<string, any>;
orderBy?: {
field: 'CREATED_AT' | 'UPDATED_AT' | 'NAME' | 'MODEL_ID';
direction: 'ASC' | 'DESC';
};
}
export function useQueryModels(args: QueryModelsArgs) {
return useQuery({
queryKey: ['models', args],
queryFn: async () => {
const data = await graphqlRequest<{ models: ModelConnection }>(MODELS_QUERY, args);
return modelConnectionSchema.parse(data.models);
},
});
}
export function useCreateModel() {
const { t } = useTranslation();
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (input: CreateModelInput) => {
const data = await graphqlRequest<{ createModel: Model }>(CREATE_MODEL_MUTATION, { input });
return modelSchema.parse(data.createModel);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['models'] });
toast.success(t('models.messages.createSuccess'));
},
onError: (error: Error) => {
toast.error(t('models.messages.createError', { error: error.message }));
},
});
}
export function useBulkCreateModels() {
const { t } = useTranslation();
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (inputs: CreateModelInput[]) => {
const data = await graphqlRequest<{ bulkCreateModels: Model[] }>(BULK_CREATE_MODELS_MUTATION, { inputs });
return data.bulkCreateModels.map((model) => modelSchema.parse(model));
},
onSuccess: (_data, variables) => {
queryClient.invalidateQueries({ queryKey: ['models'] });
toast.success(t('models.messages.bulkCreateSuccess', { count: variables.length }));
},
onError: (error: Error) => {
toast.error(t('models.messages.bulkCreateError', { error: error.message }));
},
});
}
export function useUpdateModel() {
const { t } = useTranslation();
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ id, input }: { id: string; input: UpdateModelInput }) => {
const data = await graphqlRequest<{ updateModel: Model }>(UPDATE_MODEL_MUTATION, { id, input });
return modelSchema.parse(data.updateModel);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['models'] });
toast.success(t('models.messages.updateSuccess'));
},
onError: (error: Error) => {
toast.error(t('models.messages.updateError', { error: error.message }));
},
});
}
export function useDeleteModel() {
const { t } = useTranslation();
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (id: string) => {
await graphqlRequest(DELETE_MODEL_MUTATION, { id });
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['models'] });
toast.success(t('models.messages.deleteSuccess'));
},
onError: (error: Error) => {
toast.error(t('models.messages.deleteError', { error: error.message }));
},
});
}
export function useBulkDisableModels() {
const { t } = useTranslation();
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (ids: string[]) => {
const data = await graphqlRequest<{ bulkDisableModels: boolean }>(BULK_DISABLE_MODELS_MUTATION, { ids });
return data.bulkDisableModels;
},
onSuccess: (_data, variables) => {
queryClient.invalidateQueries({ queryKey: ['models'] });
toast.success(t('models.messages.bulkDisableSuccess', { count: variables.length }));
},
onError: (error: Error) => {
toast.error(t('models.messages.bulkDisableError', { error: error.message }));
},
});
}
export function useBulkEnableModels() {
const { t } = useTranslation();
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (ids: string[]) => {
const data = await graphqlRequest<{ bulkEnableModels: boolean }>(BULK_ENABLE_MODELS_MUTATION, { ids });
return data.bulkEnableModels;
},
onSuccess: (_data, variables) => {
queryClient.invalidateQueries({ queryKey: ['models'] });
toast.success(t('models.messages.bulkEnableSuccess', { count: variables.length }));
},
onError: (error: Error) => {
toast.error(t('models.messages.bulkEnableError', { error: error.message }));
},
});
}
export interface UnassociatedChannel {
channel: {
id: string;
name: string;
type: string;
status: string;
};
models: string[];
}
export interface ModelAssociationInput {
type: 'channel_model' | 'channel_regex' | 'regex' | 'model' | 'channel_tags_model' | 'channel_tags_regex';
priority?: number;
disabled?: boolean;
channelModel?: {
channelId: number;
modelId: string;
};
channelRegex?: {
channelId: number;
pattern: string;
};
regex?: {
pattern: string;
exclude?: ExcludeAssociationInput[];
};
modelId?: {
modelId: string;
exclude?: ExcludeAssociationInput[];
};
channelTagsModel?: {
channelTags: string[];
modelId: string;
};
channelTagsRegex?: {
channelTags: string[];
pattern: string;
};
}
export interface ExcludeAssociationInput {
channelNamePattern?: string;
channelIds?: number[];
channelTags?: string[];
}
export interface ChannelModelEntry {
requestModel: string;
actualModel: string;
source: string;
}
export interface ModelChannelConnection {
channel: {
id: string;
name: string;
type: string;
status: string;
};
models: ChannelModelEntry[];
}
export function useQueryUnassociatedChannels() {
return useQuery({
queryKey: ['unassociatedChannels'],
queryFn: async () => {
const data = await graphqlRequest<{ queryUnassociatedChannels: UnassociatedChannel[] }>(QUERY_UNASSOCIATED_CHANNELS);
return data.queryUnassociatedChannels;
},
enabled: false,
});
}
const MODEL_CHANNEL_CONNECTIONS_QUERY = `
query QueryModelChannelConnections($associations: [ModelAssociationInput!]!) {
queryModelChannelConnections(associations: $associations) {
channel {
id
name
type
status
}
models {
requestModel
actualModel
source
}
}
}
`;
export function useQueryModelChannelConnections() {
return useMutation({
mutationFn: async (associations: ModelAssociationInput[]) => {
const data = await graphqlRequest<{
queryModelChannelConnections: ModelChannelConnection[];
}>(MODEL_CHANNEL_CONNECTIONS_QUERY, { associations });
return data.queryModelChannelConnections;
},
});
}