mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
feat: add token usage and top questions statistics retrieval
This commit is contained in:
parent
719ba08c6e
commit
74b1bce315
|
|
@ -192,6 +192,26 @@ const getStatistics: (
|
|||
) => Promise<Result<any>> = (application_id, data, loading) => {
|
||||
return get(`${prefix.value}/${application_id}/application_stats`, data, loading)
|
||||
}
|
||||
/**
|
||||
* 统计token消耗
|
||||
*/
|
||||
const getTokenUsage: (
|
||||
application_id: string,
|
||||
data: any,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (application_id, data, loading) => {
|
||||
return get(`${prefix.value}/${application_id}/application_token_usage`, data, loading)
|
||||
}
|
||||
/**
|
||||
* 统计提问次数
|
||||
*/
|
||||
const topQuestions: (
|
||||
application_id: string,
|
||||
data: any,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (application_id, data, loading) => {
|
||||
return get(`${prefix.value}/${application_id}/top_questions`, data, loading)
|
||||
}
|
||||
/**
|
||||
* 打开调试对话id
|
||||
* @param application_id 应用id
|
||||
|
|
@ -207,11 +227,11 @@ const open: (application_id: string, loading?: Ref<boolean>) => Promise<Result<s
|
|||
|
||||
/**
|
||||
* 生成提示词
|
||||
* @param workspace_id
|
||||
* @param model_id
|
||||
* @param application_id
|
||||
* @param data
|
||||
* @returns
|
||||
* @param workspace_id
|
||||
* @param model_id
|
||||
* @param application_id
|
||||
* @param data
|
||||
* @returns
|
||||
*/
|
||||
const generate_prompt: (workspace_id:string ,model_id:string, application_id:string,data: any) => Promise<any> = (
|
||||
workspace_id,
|
||||
|
|
@ -408,5 +428,7 @@ export default {
|
|||
speechToText,
|
||||
getMcpTools,
|
||||
postUploadFile,
|
||||
generate_prompt
|
||||
generate_prompt,
|
||||
getTokenUsage,
|
||||
topQuestions
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,6 +111,23 @@ const getStatistics: (
|
|||
) => Promise<Result<any>> = (application_id, data, loading) => {
|
||||
return get(`${prefix}/${application_id}/application_stats`, data, loading)
|
||||
}
|
||||
/**
|
||||
* 统计token消耗
|
||||
*/
|
||||
const getTokenUsage: (
|
||||
application_id: string,
|
||||
data: any,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (application_id, data, loading) => {
|
||||
return get(`${prefix}/${application_id}/application_token_usage`, data, loading)
|
||||
}
|
||||
const topQuestions: (
|
||||
application_id: string,
|
||||
data: any,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (application_id, data, loading) => {
|
||||
return get(`${prefix}/${application_id}/top_questions`, data, loading)
|
||||
}
|
||||
/**
|
||||
* 打开调试对话id
|
||||
* @param application_id 应用id
|
||||
|
|
@ -126,10 +143,10 @@ const open: (application_id: string, loading?: Ref<boolean>) => Promise<Result<s
|
|||
|
||||
/**
|
||||
* 生成提示词
|
||||
* @param application_id
|
||||
* @param model_id
|
||||
* @param data
|
||||
* @returns
|
||||
* @param application_id
|
||||
* @param model_id
|
||||
* @param data
|
||||
* @returns
|
||||
*/
|
||||
const generate_prompt: (application_id:string, model_id:string, data: any) => Promise<any> = (
|
||||
application_id,
|
||||
|
|
@ -174,7 +191,7 @@ const playDemoText: (application_id: string, data: any, loading?: Ref<boolean>)
|
|||
* 文本转语音
|
||||
*/
|
||||
const postTextToSpeech: (
|
||||
application_id: String,
|
||||
application_id: string,
|
||||
data: any,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (application_id, data, loading) => {
|
||||
|
|
@ -184,7 +201,7 @@ const postTextToSpeech: (
|
|||
* 语音转文本
|
||||
*/
|
||||
const speechToText: (
|
||||
application_id: String,
|
||||
application_id: string,
|
||||
data: any,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (application_id, data, loading) => {
|
||||
|
|
@ -289,7 +306,7 @@ const updatePlatformConfig: (
|
|||
/**
|
||||
* mcp 节点
|
||||
*/
|
||||
const getMcpTools: (application_id: String, loading?: Ref<boolean>) => Promise<Result<any>> = (
|
||||
const getMcpTools: (application_id: string, loading?: Ref<boolean>) => Promise<Result<any>> = (
|
||||
application_id,
|
||||
loading,
|
||||
) => {
|
||||
|
|
@ -320,5 +337,7 @@ export default {
|
|||
speechToText,
|
||||
getMcpTools,
|
||||
putXpackAccessToken,
|
||||
generate_prompt
|
||||
generate_prompt,
|
||||
getTokenUsage,
|
||||
topQuestions
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,14 +13,14 @@
|
|||
<el-card shadow="never">
|
||||
<div class="flex align-center ml-8 mr-8">
|
||||
<el-avatar :size="40" shape="square" :style="{ background: item.background }">
|
||||
<appIcon :iconName="item.icon" :style="{ fontSize: '24px', color: item.color }" />
|
||||
<appIcon :iconName="item.icon" :style="{ fontSize: '24px', color: item.color }"/>
|
||||
</el-avatar>
|
||||
<div class="ml-12">
|
||||
<p class="color-secondary lighter mb-4">{{ item.name }}</p>
|
||||
<div v-if="item.id !== 'starCharts'" class="flex align-baseline">
|
||||
<h2>{{ numberFormat(item.sum?.[0]) }}</h2>
|
||||
<span v-if="item.sum.length > 1" class="ml-12" style="color: #f54a45"
|
||||
>+{{ numberFormat(item.sum?.[1]) }}</span
|
||||
>+{{ numberFormat(item.sum?.[1]) }}</span
|
||||
>
|
||||
</div>
|
||||
<div v-else class="flex align-center mr-8">
|
||||
|
|
@ -47,23 +47,32 @@
|
|||
>
|
||||
<el-card shadow="never">
|
||||
<div class="p-8">
|
||||
<AppCharts height="316px" :id="item.id" type="line" :option="item.option" />
|
||||
<AppCharts height="316px" :id="item.id" type="line" :option="item.option"/>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import {ref, computed, onMounted} from 'vue'
|
||||
import AppCharts from '@/components/app-charts/index.vue'
|
||||
import { getAttrsArray, getSum } from '@/utils/array'
|
||||
import { numberFormat } from '@/utils/common'
|
||||
import { t } from '@/locales'
|
||||
import {getAttrsArray, getSum} from '@/utils/array'
|
||||
import {numberFormat} from '@/utils/common'
|
||||
import {t} from '@/locales'
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
tokenUsage: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
topQuestions: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
}
|
||||
})
|
||||
const statisticsType = computed(() => [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<div class="title flex align-center">
|
||||
<div class="edit-avatar mr-12">
|
||||
<el-avatar shape="square" :size="32" style="background: none">
|
||||
<img :src="resetUrl(detail?.icon, resetUrl('./favicon.ico'))" alt="" />
|
||||
<img :src="resetUrl(detail?.icon, resetUrl('./favicon.ico'))" alt=""/>
|
||||
</el-avatar>
|
||||
</div>
|
||||
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
<el-col :span="12" class="mt-16">
|
||||
<div class="flex">
|
||||
<el-text type="info"
|
||||
>{{ $t('views.applicationOverview.appInfo.publicAccessLink') }}
|
||||
>{{ $t('views.applicationOverview.appInfo.publicAccessLink') }}
|
||||
</el-text>
|
||||
<el-switch
|
||||
v-model="accessToken.is_active"
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
style="margin-left: 1px"
|
||||
>
|
||||
<el-icon>
|
||||
<RefreshRight />
|
||||
<RefreshRight/>
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
|
|
@ -98,12 +98,12 @@
|
|||
<el-col :span="12" class="mt-16">
|
||||
<div class="flex">
|
||||
<el-text type="info"
|
||||
>{{ $t('views.applicationOverview.appInfo.apiAccessCredentials') }}
|
||||
>{{ $t('views.applicationOverview.appInfo.apiAccessCredentials') }}
|
||||
</el-text>
|
||||
</div>
|
||||
<div class="mt-4 mb-16 url-height">
|
||||
<div>
|
||||
<el-text>API {{ $t('common.fileUpload.document') }}: </el-text>
|
||||
<el-text>API {{ $t('common.fileUpload.document') }}:</el-text>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
|
|
@ -119,8 +119,8 @@
|
|||
</span>
|
||||
|
||||
<span class="vertical-middle lighter break-all ellipsis-1">{{
|
||||
baseUrl + id
|
||||
}}</span>
|
||||
baseUrl + id
|
||||
}}</span>
|
||||
<el-tooltip effect="dark" :content="$t('common.copy')" placement="top">
|
||||
<el-button type="primary" text @click="copyClick(baseUrl + id)">
|
||||
<AppIcon iconName="app-copy"></AppIcon>
|
||||
|
|
@ -134,7 +134,7 @@
|
|||
v-if="permissionPrecise.overview_api_key(id)"
|
||||
>
|
||||
<el-icon class="mr-4">
|
||||
<Key />
|
||||
<Key/>
|
||||
</el-icon>
|
||||
{{ $t('views.applicationOverview.appInfo.apiKey') }}
|
||||
</el-button>
|
||||
|
|
@ -173,7 +173,8 @@
|
|||
/>
|
||||
</div>
|
||||
<div v-loading="statisticsLoading">
|
||||
<StatisticsCharts :data="statisticsData" />
|
||||
<StatisticsCharts :data="statisticsData" :token-usage="tokenUsage"
|
||||
:top-questions="topQuestions"/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
|
|
@ -184,17 +185,17 @@
|
|||
:data="detail"
|
||||
:api-input-params="mapToUrlParams(apiInputParams)"
|
||||
/>
|
||||
<APIKeyDialog ref="APIKeyDialogRef" />
|
||||
<APIKeyDialog ref="APIKeyDialogRef"/>
|
||||
|
||||
<!-- 社区版访问限制 -->
|
||||
<component :is="currentLimitDialog" ref="LimitDialogRef" @refresh="refresh" />
|
||||
<component :is="currentLimitDialog" ref="LimitDialogRef" @refresh="refresh"/>
|
||||
<!-- 显示设置 -->
|
||||
<component :is="currentDisplaySettingDialog" ref="DisplaySettingDialogRef" @refresh="refresh" />
|
||||
<component :is="currentDisplaySettingDialog" ref="DisplaySettingDialogRef" @refresh="refresh"/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted, shallowRef, nextTick } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import {ref, computed, onMounted, shallowRef, nextTick} from 'vue'
|
||||
import {useRoute} from 'vue-router'
|
||||
import EmbedDialog from './component/EmbedDialog.vue'
|
||||
import APIKeyDialog from './component/APIKeyDialog.vue'
|
||||
import LimitDialog from './component/LimitDialog.vue'
|
||||
|
|
@ -202,20 +203,20 @@ import XPackLimitDrawer from './xpack-component/XPackLimitDrawer.vue'
|
|||
import DisplaySettingDialog from './component/DisplaySettingDialog.vue'
|
||||
import XPackDisplaySettingDialog from './xpack-component/XPackDisplaySettingDialog.vue'
|
||||
import StatisticsCharts from './component/StatisticsCharts.vue'
|
||||
import { nowDate, beforeDay } from '@/utils/time'
|
||||
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||
import { copyClick } from '@/utils/clipboard'
|
||||
import { resetUrl } from '@/utils/common'
|
||||
import { mapToUrlParams } from '@/utils/application'
|
||||
import { t } from '@/locales'
|
||||
import { EditionConst } from '@/utils/permission/data'
|
||||
import { hasPermission } from '@/utils/permission/index'
|
||||
import {nowDate, beforeDay} from '@/utils/time'
|
||||
import {MsgSuccess, MsgConfirm} from '@/utils/message'
|
||||
import {copyClick} from '@/utils/clipboard'
|
||||
import {resetUrl} from '@/utils/common'
|
||||
import {mapToUrlParams} from '@/utils/application'
|
||||
import {t} from '@/locales'
|
||||
import {EditionConst} from '@/utils/permission/data'
|
||||
import {hasPermission} from '@/utils/permission/index'
|
||||
import permissionMap from '@/permission'
|
||||
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
|
||||
import {loadSharedApi} from '@/utils/dynamics-api/shared-api'
|
||||
|
||||
const route = useRoute()
|
||||
const {
|
||||
params: { id },
|
||||
params: {id},
|
||||
} = route as any
|
||||
|
||||
const apiType = computed(() => {
|
||||
|
|
@ -287,6 +288,8 @@ const daterange = ref({
|
|||
|
||||
const statisticsLoading = ref(false)
|
||||
const statisticsData = ref([])
|
||||
const tokenUsage = ref([])
|
||||
const topQuestions = ref([])
|
||||
|
||||
const apiInputParams = ref([])
|
||||
|
||||
|
|
@ -308,7 +311,7 @@ function openDisplaySettingDialog() {
|
|||
}
|
||||
nextTick(() => {
|
||||
if (currentDisplaySettingDialog.value == XPackDisplaySettingDialog) {
|
||||
loadSharedApi({ type: 'application', systemType: apiType.value })
|
||||
loadSharedApi({type: 'application', systemType: apiType.value})
|
||||
.getApplicationSetting(id)
|
||||
.then((ok: any) => {
|
||||
DisplaySettingDialogRef.value?.open(ok.data, detail.value)
|
||||
|
|
@ -351,11 +354,21 @@ function changeDayRangeHandle(val: string) {
|
|||
}
|
||||
|
||||
function getAppStatistics() {
|
||||
loadSharedApi({ type: 'application', systemType: apiType.value })
|
||||
loadSharedApi({type: 'application', systemType: apiType.value})
|
||||
.getStatistics(id, daterange.value, statisticsLoading)
|
||||
.then((res: any) => {
|
||||
statisticsData.value = res.data
|
||||
})
|
||||
loadSharedApi({type: 'application', systemType: apiType.value})
|
||||
.getTokenUsage(id, daterange.value, statisticsLoading)
|
||||
.then((res: any) => {
|
||||
tokenUsage.value = res.data
|
||||
})
|
||||
loadSharedApi({type: 'application', systemType: apiType.value})
|
||||
.topQuestions(id, daterange.value, statisticsLoading)
|
||||
.then((res: any) => {
|
||||
topQuestions.value = res.data
|
||||
})
|
||||
}
|
||||
|
||||
function refreshAccessToken() {
|
||||
|
|
@ -374,7 +387,8 @@ function refreshAccessToken() {
|
|||
const str = t('views.applicationOverview.appInfo.refreshToken.refreshSuccess')
|
||||
updateAccessToken(obj, str)
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch(() => {
|
||||
})
|
||||
}
|
||||
|
||||
async function changeState(bool: boolean) {
|
||||
|
|
@ -392,7 +406,7 @@ async function changeState(bool: boolean) {
|
|||
}
|
||||
|
||||
async function updateAccessToken(obj: any, str: string) {
|
||||
loadSharedApi({ type: 'application', systemType: apiType.value })
|
||||
loadSharedApi({type: 'application', systemType: apiType.value})
|
||||
.putAccessToken(id as string, obj, loading)
|
||||
.then((res: any) => {
|
||||
accessToken.value = res?.data
|
||||
|
|
@ -409,7 +423,7 @@ function openDialog() {
|
|||
}
|
||||
|
||||
function getAccessToken() {
|
||||
loadSharedApi({ type: 'application', systemType: apiType.value })
|
||||
loadSharedApi({type: 'application', systemType: apiType.value})
|
||||
.getAccessToken(id, loading)
|
||||
.then((res: any) => {
|
||||
accessToken.value = res?.data
|
||||
|
|
@ -417,7 +431,7 @@ function getAccessToken() {
|
|||
}
|
||||
|
||||
function getDetail() {
|
||||
loadSharedApi({ type: 'application', systemType: apiType.value })
|
||||
loadSharedApi({type: 'application', systemType: apiType.value})
|
||||
.getApplicationDetail(id, loading)
|
||||
.then((res: any) => {
|
||||
detail.value = res.data
|
||||
|
|
@ -426,20 +440,20 @@ function getDetail() {
|
|||
.map((v: any) => {
|
||||
apiInputParams.value = v.properties.api_input_field_list
|
||||
? v.properties.api_input_field_list.map((v: any) => {
|
||||
return {
|
||||
name: v.variable,
|
||||
value: v.default_value,
|
||||
}
|
||||
})
|
||||
return {
|
||||
name: v.variable,
|
||||
value: v.default_value,
|
||||
}
|
||||
})
|
||||
: v.properties.input_field_list
|
||||
? v.properties.input_field_list
|
||||
.filter((v: any) => v.assignment_method === 'api_input')
|
||||
.map((v: any) => {
|
||||
return {
|
||||
name: v.variable,
|
||||
value: v.default_value,
|
||||
}
|
||||
})
|
||||
.filter((v: any) => v.assignment_method === 'api_input')
|
||||
.map((v: any) => {
|
||||
return {
|
||||
name: v.variable,
|
||||
value: v.default_value,
|
||||
}
|
||||
})
|
||||
: []
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue