Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,6 @@ export function ModelsActionDialog() {
icon: data.icon,
group: data.group,
modelCard: data.modelCard,
settings: data.settings,
remark: data.remark,
};
await updateModel.mutateAsync({ id: currentRow.id, input: updateData });
Expand Down
171 changes: 112 additions & 59 deletions frontend/src/features/models/components/models-association-dialog.tsx

Large diffs are not rendered by default.

83 changes: 78 additions & 5 deletions frontend/src/features/models/components/models-columns.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useCallback, useState } from 'react';
import { format } from 'date-fns';
import { ColumnDef, Row, Table } from '@tanstack/react-table';
import { IconCheck, IconX, IconLink, IconChevronDown, IconChevronRight } from '@tabler/icons-react';
import { CellContext, ColumnDef, Row, Table } from '@tanstack/react-table';
import { IconCheck, IconX, IconLink, IconChevronDown, IconChevronRight, IconPhotoOff, IconScanEye } from '@tabler/icons-react';
import * as Icons from '@lobehub/icons';
import { useTranslation } from 'react-i18next';
import { usePermissions } from '@/hooks/usePermissions';
Expand Down Expand Up @@ -80,6 +80,69 @@ function AssociationRulesCell({ row }: { row: Row<Model> }) {
);
}

function ImageHandlingCell({ row, table }: CellContext<Model, unknown>) {
const { t } = useTranslation();
const { setOpen, setCurrentRow } = useModels();
const { channelPermissions } = usePermissions();
const model = row.original;
const targetModelID = model.settings?.visionDelegation?.targetModelID;
const enabled = Boolean(model.settings?.visionDelegation?.enabled && targetModelID);
const fallbackEnabled = model.settings?.unsupportedImageFallback?.enabled ?? false;
const targetModel = enabled ? table.options.data.find((candidate) => candidate.modelID === targetModelID) : undefined;
const targetLabel = targetModel?.name || targetModelID;
const targetDescription = targetModel ? `${targetModel.name} (${targetModel.modelID})` : targetModelID;

const handleOpen = useCallback(() => {
setCurrentRow(model);
setOpen('visionDelegation');
}, [model, setCurrentRow, setOpen]);

const content = enabled ? (
<span className='block max-w-full truncate text-xs font-medium'>{targetLabel}</span>
) : fallbackEnabled ? (
<IconPhotoOff className='h-4 w-4 text-amber-600 dark:text-amber-400' />
) : (
<IconScanEye className='text-muted-foreground h-4 w-4' />
);

const tooltipContent = enabled ? (
<div className='space-y-1'>
<div>{targetDescription}</div>
{fallbackEnabled && <div>{t('models.dialogs.unsupportedImageFallback.enabledStatus')}</div>}
</div>
) : fallbackEnabled ? (
t('models.dialogs.unsupportedImageFallback.enabledStatus')
) : (
t('models.dialogs.imageHandling.configure')
);

return (
<div className='flex justify-center'>
<Tooltip>
<TooltipTrigger asChild>
{channelPermissions.canWrite ? (
<Button
type='button'
variant='ghost'
size={enabled ? 'sm' : 'icon'}
className={enabled ? 'h-8 max-w-full px-2' : 'h-8 w-8'}
onClick={handleOpen}
aria-label={t('models.dialogs.imageHandling.configure')}
>
{content}
</Button>
) : (
<span className={enabled ? 'block max-w-full truncate px-2 text-xs font-medium' : 'flex h-8 w-8 items-center justify-center'}>
{content}
</span>
)}
</TooltipTrigger>
<TooltipContent>{tooltipContent}</TooltipContent>
</Tooltip>
</div>
);
}

export const createColumns = (t: ReturnType<typeof useTranslation>['t'], canWrite: boolean = true): ColumnDef<Model>[] => {
return [
{
Expand Down Expand Up @@ -231,7 +294,7 @@ export const createColumns = (t: ReturnType<typeof useTranslation>['t'], canWrit
header: ({ column }) => <DataTableColumnHeader column={column} title={t('models.columns.toolCall')} />,
cell: ({ row }) => {
const model = row.original;
const toolCall = model.modelCard?.toolCall;
const toolCall = (model.effectiveModelCard || model.modelCard)?.toolCall;

return (
<div className='flex justify-center'>
Expand All @@ -241,6 +304,17 @@ export const createColumns = (t: ReturnType<typeof useTranslation>['t'], canWrit
},
enableSorting: false,
},
{
id: 'visionDelegation',
header: ({ column }) => (
<DataTableColumnHeader column={column} title={t('models.columns.imageHandling')} className='w-full text-center' />
),
cell: ImageHandlingCell,
enableSorting: false,
meta: {
className: 'w-32 min-w-32 max-w-32 text-center',
},
},
// {
// id: 'context',
// header: ({ column }) => <DataTableColumnHeader column={column} title={t('models.columns.context')} />,
Expand Down Expand Up @@ -309,8 +383,7 @@ export const createColumns = (t: ReturnType<typeof useTranslation>['t'], canWrit
},
enableSorting: false,
},

{
{
accessorKey: 'createdAt',
header: ({ column }) => <DataTableColumnHeader column={column} title={t('common.columns.createdAt')} />,
cell: ({ row }) => {
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/features/models/components/models-dialogs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ModelsBulkEnableDialog } from './models-bulk-enable-dialog';
import { ModelsDeleteDialog } from './models-delete-dialog';
import { ModelSettingsDialog } from './models-settings-dialog';
import { ModelsUnassociatedDialog } from './models-unassociated-dialog';
import { ModelsVisionDelegationDialog } from './models-vision-delegation-dialog';

export function ModelsDialogs() {
const { open } = useModels();
Expand All @@ -19,6 +20,7 @@ export function ModelsDialogs() {
{open === 'delete' && <ModelsDeleteDialog />}
{open === 'archive' && <ModelsArchiveDialog />}
{(open === 'association' || open === 'developerAssociation') && <ModelsAssociationDialog />}
{open === 'visionDelegation' && <ModelsVisionDelegationDialog />}
{open === 'settings' && <ModelSettingsDialog />}
{open === 'unassociated' && <ModelsUnassociatedDialog />}
<ModelsBulkDisableDialog />
Expand Down
Loading