fix: chat not pass doc if not support vision (#39461)

This commit is contained in:
Joel 2026-07-23 18:01:43 +08:00 committed by GitHub
parent 0198e32447
commit 2beafdc457
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 32 additions and 15 deletions

View File

@ -45,7 +45,7 @@ const ConfigDocument: FC = () => {
if (!isShowDocumentConfig || (readonly && !isDocumentEnabled)) return null
return (
<div className="mt-2 flex items-center gap-2 rounded-xl border-t-[0.5px] border-l-[0.5px] bg-background-section-burn p-2">
<div className="mt-2 flex items-center gap-2 rounded-xl border-t-[0.5px] border-l-[0.5px] border-effects-highlight bg-background-section-burn p-2">
<div className="shrink-0 p-1">
<div className="rounded-lg border-[0.5px] border-divider-subtle bg-util-colors-indigo-indigo-600 p-1 shadow-xs">
<Document className="size-4 text-text-primary-on-surface" />
@ -64,7 +64,7 @@ const ConfigDocument: FC = () => {
</div>
{!readonly && (
<div className="flex shrink-0 items-center">
<div className="mr-3 ml-1 h-3.5 w-px bg-divider-subtle"></div>
<div className="mr-3 ml-1 h-3.5 w-px bg-divider-regular"></div>
<Switch checked={isDocumentEnabled} onCheckedChange={handleChange} size="md" />
</div>
)}

View File

@ -16,6 +16,7 @@ import {
ModelTypeEnum,
} from '@/app/components/header/account-setting/model-provider-page/declarations'
import { CollectionType } from '@/app/components/tools/types'
import { SupportUploadFileTypes } from '@/app/components/workflow/types'
import { PromptMode } from '@/models/debug'
import { renderWithAccountProfile as render } from '@/test/console/account-profile'
import { AgentStrategy, AppModeEnum, ModelModeType, Resolution, TransferMethod } from '@/types/app'
@ -461,6 +462,16 @@ const mockFile: FileEntity = {
supportFileType: 'image',
}
const mockDocumentFile: FileEntity = {
id: 'file-2',
name: 'test.pdf',
size: 456,
type: 'application/pdf',
progress: 100,
transferMethod: TransferMethod.local_file,
supportFileType: SupportUploadFileTypes.document,
}
// Mock Chat component (complex with many dependencies)
// This is a pragmatic mock that tests the integration at DebugWithSingleModel level
vi.mock('@/app/components/base/chat/chat', () => ({
@ -519,6 +530,13 @@ vi.mock('@/app/components/base/chat/chat', () => ({
>
Send With Files
</button>
<button
data-testid="send-with-document"
onClick={() => onSend?.('test message', [mockDocumentFile])}
disabled={isResponding || readonly || inputDisabled}
>
Send With Document
</button>
{isResponding && (
<button data-testid="stop-button" onClick={onStopResponding}>
Stop
@ -985,7 +1003,7 @@ describe('DebugWithSingleModel', () => {
// File Upload Tests
describe('File Upload', () => {
it('should not include files when vision is not supported', async () => {
it('should include document files when document is supported without vision', async () => {
mockUseDebugConfigurationContext.mockReturnValue({
...mockDebugConfigContext,
modelConfig: createMockModelConfig({
@ -1006,7 +1024,7 @@ describe('DebugWithSingleModel', () => {
model: 'gpt-3.5-turbo',
label: { en_US: 'GPT-3.5', zh_Hans: 'GPT-3.5' },
model_type: ModelTypeEnum.textGeneration,
features: [], // No vision
features: [ModelFeatureEnum.document],
fetch_from: ConfigurationMethodEnum.predefinedModel,
model_properties: {},
deprecated: false,
@ -1026,14 +1044,21 @@ describe('DebugWithSingleModel', () => {
render(<DebugWithSingleModel ref={ref as RefObject<DebugWithSingleModelRefType>} />)
fireEvent.click(screen.getByTestId('send-with-files'))
fireEvent.click(screen.getByTestId('send-with-document'))
await waitFor(() => {
expect(mockSsePost).toHaveBeenCalled()
})
const body = mockSsePost.mock.calls[0]![1].body
expect(body.files).toEqual([])
expect(body.files).toEqual([
{
type: SupportUploadFileTypes.document,
transfer_method: TransferMethod.local_file,
url: '',
upload_file_id: '',
},
])
})
it('should support files when vision is enabled', async () => {

View File

@ -9,7 +9,6 @@ import Chat from '@/app/components/base/chat/chat'
import { useChat } from '@/app/components/base/chat/chat/hooks'
import { getLastAnswer, isValidGeneratedAnswer } from '@/app/components/base/chat/utils'
import { useFeatures } from '@/app/components/base/features/hooks'
import { ModelFeatureEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import { userProfileAtom } from '@/context/account-state'
import { useDebugConfigurationContext } from '@/context/debug-configuration'
import { useProviderContext } from '@/context/provider-context'
@ -97,13 +96,6 @@ const DebugWithSingleModel = ({
(message, files, isRegenerate = false, parentAnswer: ChatItem | null = null) => {
if (!canTestAndRun) return
if (checkCanSend && !checkCanSend()) return
const currentProvider = textGenerationModelList.find(
(item) => item.provider === modelConfig.provider,
)
const currentModel = currentProvider?.models.find(
(model) => model.model === modelConfig.model_id,
)
const supportVision = currentModel?.features?.includes(ModelFeatureEnum.vision)
const configData = {
...config,
@ -122,7 +114,7 @@ const DebugWithSingleModel = ({
parent_message_id: (isRegenerate ? parentAnswer?.id : getLastAnswer(chatList)?.id) || null,
}
if ((config.file_upload as any)?.enabled && files?.length && supportVision) data.files = files
if ((config.file_upload as any)?.enabled && files?.length) data.files = files
handleSend(`apps/${appId}/chat-messages`, data, {
onGetConversationMessages: (conversationId, getAbortController) =>