Skip to content

Commit

Permalink
Merge pull request #36 from OVINC-CN/feat_vision
Browse files Browse the repository at this point in the history
feat(vision): full support of vision model
  • Loading branch information
OrenZhang authored Dec 11, 2024
2 parents 6f94167 + d90bdc7 commit 2fd4b23
Show file tree
Hide file tree
Showing 11 changed files with 19 additions and 177 deletions.
Binary file removed public/chatgpt.png
Binary file not shown.
Binary file modified public/favicon.ico
Binary file not shown.
Binary file modified public/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/favicon.webp
Binary file not shown.
Binary file added public/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 5 additions & 3 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
style="cursor: pointer"
@click="goTo('Chat')"
>
<div>
ChatGPT
</div>
<img
height="32px"
src="/logo.png"
alt="logo"
>
</div>
<a-space id="app-header-right">
<icon-fullscreen-exit
Expand Down
14 changes: 0 additions & 14 deletions src/api/cos.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,3 @@ export const getCOSUploadTempKeyAPI = (filename, purpose, tcaptcha) => new Promi
(err) => reject(err),
);
});

export const extractFileAPI = (filePath) => new Promise((resolve, reject) => {
http.post('/cos/extract_file/', {file_path: filePath}).then(
(res) => resolve(res),
(err) => reject(err),
);
});

export const extractFileStatusAPI = (filePath) => new Promise((resolve, reject) => {
http.get('/cos/extract_file_status/', {params: {file_path: filePath}}).then(
(res) => resolve(res),
(err) => reject(err),
);
});
8 changes: 0 additions & 8 deletions src/api/tool.js

This file was deleted.

162 changes: 12 additions & 150 deletions src/components/ChatInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ import {useStore} from 'vuex';
import {useI18n} from 'vue-i18n';
import globalContext from '../context';
import {checkTCaptcha} from '@/utils/tcaptcha';
import {extractFileAPI, extractFileStatusAPI, getCOSConfigAPI, getCOSUploadTempKeyAPI} from '@/api/cos';
import {getCOSConfigAPI, getCOSUploadTempKeyAPI} from '@/api/cos';
import {loadCOSClient} from '@/utils/cos';
import {IconFile, IconDelete} from '@arco-design/web-vue/es/icon';
import {listSystemPresetAPI} from '@/api/model';
import {listToolsAPI} from '@/api/tool';
// props
const props = defineProps({
Expand Down Expand Up @@ -133,10 +131,6 @@ const doChat = async () => {
if (props.systemDefine) {
params.messages.unshift({role: 'system', content: props.systemDefine});
}
// use tool
if (currentTool.value) {
params['tools'] = [currentTool.value];
}
// call api
let key = '';
await preCheckAPI(params)
Expand Down Expand Up @@ -312,44 +306,6 @@ onMounted(() => {
}
});
// tools
const tools = ref([]);
const loadTools = () => {
listToolsAPI().then((res) => tools.value = res.data);
};
onMounted(() => loadTools());
const currentTool = ref('');
const currentToolDesc = computed(() => {
let val = '';
tools.value.forEach((item) => {
if (item.id === currentTool.value) {
val = item.desc;
}
});
return val ? val : '';
});
const toolVisible = ref(false);
const changeTool = () => toolVisible.value = true;
const doSubmitTool = () => {
toolVisible.value = false;
localStorage.setItem(localToolKey.value, JSON.stringify(currentTool.value));
};
const resetTool = () => {
toolVisible.value = false;
currentTool.value = '';
currentToolDesc.value = '';
doSubmitTool();
};
const localToolKey = ref('local-tool');
onMounted(() => {
const value = localStorage.getItem(localToolKey.value);
if (value) {
try {
currentTool.value = JSON.parse(value);
} catch (_) {}
}
});
// upload file
const uploadEnabled = ref(false);
onMounted(() => getCOSConfigAPI().then((res) => uploadEnabled.value = res.data.upload_file_enabled));
Expand Down Expand Up @@ -387,56 +343,25 @@ const doUploadFile = (file) => {
Message.error(err.message);
} else {
const filePath = `${credentials.cos_url}/${credentials.key}`;
const fileSuffix = credentials.key.split('.').pop();
let signedFilePath = new URL(`${credentials.cos_url}/${credentials.key}`);
const signedFilePath = new URL(`${credentials.cos_url}/${credentials.key}`);
if (credentials.cdn_sign) {
signedFilePath.searchParams.append(credentials.cdn_sign_param, credentials.cdn_sign);
}
if (credentials.image_format) {
signedFilePath.searchParams.append(credentials.image_format, '');
}
signedFilePath = signedFilePath.toString();
extractFileAPI(filePath).then(
() => {
checkExtractStatus(filePath, signedFilePath);
},
(err) => {
emits('setChatLoading', false);
Message.error(err.response.data.message);
},
);
promptForm.value.file = filePath;
promptForm.value.previewFile = signedFilePath.toString();
}
emits('setChatLoading', false);
});
},
(err) => {
emits('setChatLoading', false);
Message.error(err.response.data.message);
},
);
});
};
const checkExtractStatus = (filePath, signedFilePath) => {
setTimeout(() => {
extractFileStatusAPI(filePath).then(
(res) => {
if (res.data.is_finished) {
if (res.data.is_success) {
promptForm.value.file = filePath;
promptForm.value.previewFile = signedFilePath;
} else {
Message.error(i18n.t('ExtractFileFailed'));
}
emits('setChatLoading', false);
} else {
checkExtractStatus(filePath, signedFilePath);
}
},
(err) => {
emits('setChatLoading', false);
Message.error(err.response.data.message);
},
);
}, 2000);
});
};
// paste
Expand All @@ -450,7 +375,7 @@ const handlePaste = (e) => {
const item = items[i];
if (item.kind === 'file') {
const file = item.getAsFile();
if (file.type.indexOf('image/') !== -1 || file.type.indexOf('application/') !== -1 || file.type.indexOf('text/') !== -1 ) {
if (file.type.indexOf('image/') !== -1) {
doUploadFile(file);
}
}
Expand Down Expand Up @@ -488,7 +413,7 @@ const handleDrop = (e) => {
if (files.length > 0) {
const file = files[0];
console.log(file.type);
if (file.type.indexOf('image/') !== -1 || file.type.indexOf('application/') !== -1 || file.type.indexOf('text/') !== -1 ) {
if (file.type.indexOf('image/') !== -1) {
doUploadFile(file);
}
}
Expand Down Expand Up @@ -517,7 +442,7 @@ defineExpose({reGenerate, promptForm});
ref="fileUploadInput"
style="display: none"
type="file"
accept="image/*, application/*, text/*"
accept="image/*"
@change="handleFileChange"
>
<a-form
Expand Down Expand Up @@ -546,7 +471,7 @@ defineExpose({reGenerate, promptForm});
<icon-robot />
</a-button>
<a-button
v-if="showEditBox"
v-if="showEditBox && model?.config?.support_system_define"
:disabled="chatLoading"
@click="changePreset"
class="chat-input-left-button"
Expand All @@ -556,24 +481,14 @@ defineExpose({reGenerate, promptForm});
<icon-bulb />
</a-button>
<a-button
v-if="showEditBox && (tools.length > 0 || currentTool)"
:disabled="chatLoading"
@click="changeTool"
class="chat-input-left-button"
:type="currentTool ? 'primary': undefined"
:status="currentTool ? 'warning' : undefined"
>
<icon-apps />
</a-button>
<a-button
v-if="uploadEnabled && showEditBox"
v-if="uploadEnabled && showEditBox && model?.config?.support_vision"
:disabled="chatLoading"
@click="customUpload"
:type="promptForm.file ? 'primary': undefined"
:status="promptForm.file ? 'warning' : undefined"
class="chat-input-left-button"
>
<icon-file />
<icon-image />
</a-button>
</a-space>
<a-space>
Expand Down Expand Up @@ -633,57 +548,6 @@ defineExpose({reGenerate, promptForm});
</a-spin>
</a-form-item>
</a-form>
<a-modal
v-model:visible="toolVisible"
:footer="false"
:esc-to-close="true"
>
<template #title>
<div style="text-align: left; width: 100%">
{{ $t('Tools') }}
</div>
</template>
<a-space
direction="vertical"
id="chat-input-tool-choose"
>
<a-select
:placeholder="$t('PleaseChooseTool')"
v-model="currentTool"
>
<a-option
v-for="item in tools"
:key="item.id"
:value="item.id"
:label="item.name"
/>
</a-select>
<a-textarea
v-model="currentToolDesc"
:auto-size="{minRows: 3, maxRows: 10}"
:placeholder="$t('PleaseChooseTool')"
/>
<div class="model-tool-tips">
{{ $t('ToolUseTips') }}
</div>
<a-space style="width: 100%; display: flex; justify-content: flex-end">
<a-button
v-if="currentTool"
type="primary"
status="warning"
@click="resetTool"
>
{{ $t('Remove') }}
</a-button>
<a-button
type="primary"
@click="doSubmitTool"
>
{{ $t('Save') }}
</a-button>
</a-space>
</a-space>
</a-modal>
<a-modal
v-model:visible="maxMessageVisible"
:footer="false"
Expand Down Expand Up @@ -867,13 +731,11 @@ defineExpose({reGenerate, promptForm});
.model-ignore-system-tips,
.model-context-tips,
.model-tool-tips,
.model-price-tips {
color: var(--color-neutral-6);
font-size: 12px;
}
#chat-input-tool-choose,
#chat-input-system-define-content > :deep(.arco-space-item) {
width: 100%;
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/MessageContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const onImageClick = (images, index) => emits('onImageClick', images[index]);
>
<img
alt="ChatGPT Logo"
src="/chatgpt.png"
src="/logo.png"
>
</a-avatar>
<div
Expand Down
2 changes: 1 addition & 1 deletion src/components/MessageDisplay.vue
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ const onImageClick = (url) => {
<div style="width: 60px; height: 60px">
<img
alt="ChatGPT Logo"
src="/chatgpt.png"
src="/favicon.png"
style="max-width: 100%; max-height: 100%"
>
</div>
Expand Down

0 comments on commit 2fd4b23

Please sign in to comment.