mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-31 02:02:48 +00:00
feat: application chat api (#3574)
This commit is contained in:
parent
4ffd80f184
commit
34842e4ae4
|
|
@ -153,8 +153,9 @@ def write_context(node_variable: Dict, workflow_variable: Dict, node: INode, wor
|
|||
reasoning_result = reasoning.get_reasoning_content(response)
|
||||
reasoning_result_end = reasoning.get_end_reasoning_content()
|
||||
content = reasoning_result.get('content') + reasoning_result_end.get('content')
|
||||
if 'reasoning_content' in response.response_metadata:
|
||||
reasoning_content = response.response_metadata.get('reasoning_content', '')
|
||||
meta = {**response.response_metadata, **response.additional_kwargs}
|
||||
if 'reasoning_content' in meta:
|
||||
reasoning_content = meta.get('reasoning_content', '')
|
||||
else:
|
||||
reasoning_content = reasoning_result.get('reasoning_content') + reasoning_result_end.get('reasoning_content')
|
||||
_write_context(node_variable, workflow_variable, node, workflow, content, reasoning_content)
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ urlpatterns = [
|
|||
path('embed', views.ChatEmbedView.as_view()),
|
||||
path('auth/anonymous', views.AnonymousAuthentication.as_view()),
|
||||
path('profile', views.AuthProfile.as_view()),
|
||||
path('application/profile', views.ApplicationProfile.as_view()),
|
||||
path('chat_message/<str:chat_id>', views.ChatView.as_view()),
|
||||
path('open', views.OpenView.as_view()),
|
||||
path('application/profile', views.ApplicationProfile.as_view(), name='profile'),
|
||||
path('chat_message/<str:chat_id>', views.ChatView.as_view(), name='chat'),
|
||||
path('open', views.OpenView.as_view(), name='open'),
|
||||
path('text_to_speech', views.TextToSpeech.as_view()),
|
||||
path('speech_to_text', views.SpeechToText.as_view()),
|
||||
path('captcha', views.CaptchaView.as_view(), name='captcha'),
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ from common.utils.cache_util import get_cache
|
|||
use_get_data=lambda secret_key, use_get_data: use_get_data,
|
||||
version=Cache_Version.APPLICATION_API_KEY.get_version())
|
||||
def get_application_api_key(secret_key, use_get_data):
|
||||
application_api_key = QuerySet(ApplicationApiKey).filter(secret_key=secret_key).first()
|
||||
application_api_key = QuerySet(ApplicationApiKey).filter(secret_key=secret_key[7:]).first()
|
||||
return {'allow_cross_domain': application_api_key.allow_cross_domain,
|
||||
'cross_domain_list': application_api_key.cross_domain_list}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
# coding=utf-8
|
||||
"""
|
||||
@project: maxkb
|
||||
@Author:虎
|
||||
@file: init_doc.py
|
||||
@date:2024/5/24 14:11
|
||||
@desc:
|
||||
"""
|
||||
import hashlib
|
||||
|
||||
from django.urls import path, URLPattern
|
||||
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView, SpectacularRedocView
|
||||
|
||||
from maxkb.const import CONFIG
|
||||
|
||||
chat_api_prefix = CONFIG.get_chat_path()[1:] + '/api/'
|
||||
|
||||
|
||||
def init_app_doc(system_urlpatterns):
|
||||
system_urlpatterns += [
|
||||
path('schema/', SpectacularAPIView.as_view(), name='schema'), # schema的配置文件的路由,下面两个ui也是根据这个配置文件来生成的
|
||||
path('doc/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), # swagger-ui的路由
|
||||
path('redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), # redoc的路由
|
||||
]
|
||||
|
||||
|
||||
def init_chat_doc(system_urlpatterns, chat_urlpatterns):
|
||||
system_urlpatterns += [
|
||||
path('doc_chat_schema/',
|
||||
SpectacularAPIView.as_view(patterns=[
|
||||
URLPattern(pattern=f'{chat_api_prefix}{str(url.pattern)}', callback=url.callback,
|
||||
default_args=url.default_args,
|
||||
name=url.name) for url in chat_urlpatterns if
|
||||
['chat', 'open', 'profile'].__contains__(url.name)]),
|
||||
name='chat_schema'), # schema的配置文件的路由,下面两个ui也是根据这个配置文件来生成的
|
||||
path('doc_chat/', SpectacularSwaggerView.as_view(url_name='chat_schema'), name='swagger-ui'), # swagger-ui的路由
|
||||
path('redoc_chat/', SpectacularRedocView.as_view(url_name='chat_schema'), name='redoc'), # redoc的路由
|
||||
]
|
||||
|
||||
|
||||
def encrypt(text):
|
||||
md5 = hashlib.md5()
|
||||
md5.update(text.encode())
|
||||
result = md5.hexdigest()
|
||||
return result
|
||||
|
||||
|
||||
def get_call(application_urlpatterns, patterns, params, func):
|
||||
def run():
|
||||
if params['valid']():
|
||||
func(*params['get_params'](application_urlpatterns, patterns))
|
||||
|
||||
return run
|
||||
|
||||
|
||||
init_list = [(init_app_doc, {'valid': lambda: CONFIG.get('DOC_PASSWORD') is not None and encrypt(
|
||||
CONFIG.get('DOC_PASSWORD')) == 'd4fc097197b4b90a122b92cbd5bbe867',
|
||||
'get_call': get_call,
|
||||
'get_params': lambda application_urlpatterns, patterns: (application_urlpatterns,)}),
|
||||
(init_chat_doc, {'valid': lambda: CONFIG.get('DOC_PASSWORD') is not None and encrypt(
|
||||
CONFIG.get('DOC_PASSWORD')) == 'd4fc097197b4b90a122b92cbd5bbe867' or True, 'get_call': get_call,
|
||||
'get_params': lambda application_urlpatterns, patterns: (
|
||||
application_urlpatterns, patterns)})]
|
||||
|
||||
|
||||
def init_doc(system_urlpatterns, chat_patterns):
|
||||
for init, params in init_list:
|
||||
if params['valid']():
|
||||
get_call(system_urlpatterns, chat_patterns, params, init)()
|
||||
|
|
@ -21,9 +21,10 @@ from django.http import HttpResponse, HttpResponseRedirect
|
|||
from django.templatetags.static import static as _static
|
||||
from django.urls import path, re_path, include
|
||||
from django.views import static
|
||||
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
|
||||
from rest_framework import status
|
||||
|
||||
from chat.urls import urlpatterns as chat_urlpatterns
|
||||
from common.init.init_doc import init_doc
|
||||
from common.result import Result
|
||||
from maxkb import settings
|
||||
from maxkb.conf import PROJECT_DIR
|
||||
|
|
@ -47,11 +48,7 @@ urlpatterns = [
|
|||
path(f'{admin_ui_prefix[1:]}/', include('oss.retrieval_urls')),
|
||||
path(f'{chat_ui_prefix[1:]}/', include('oss.retrieval_urls')),
|
||||
]
|
||||
urlpatterns += [
|
||||
path('schema/', SpectacularAPIView.as_view(), name='schema'), # schema的配置文件的路由,下面两个ui也是根据这个配置文件来生成的
|
||||
path('doc/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), # swagger-ui的路由
|
||||
path('redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), # redoc的路由
|
||||
]
|
||||
init_doc(urlpatterns, chat_urlpatterns)
|
||||
urlpatterns.append(
|
||||
re_path(r'^static/(?P<path>.*)$', static.serve, {'document_root': settings.STATIC_ROOT}, name='static'),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -21,18 +21,12 @@
|
|||
<el-row :gutter="12">
|
||||
<el-col :span="12" class="mt-16">
|
||||
<div class="flex">
|
||||
<el-text type="info"
|
||||
>{{ $t('views.applicationOverview.appInfo.publicAccessLink') }}
|
||||
<el-text type="info">{{ $t('views.applicationOverview.appInfo.publicAccessLink') }}
|
||||
</el-text>
|
||||
<el-switch
|
||||
v-model="accessToken.is_active"
|
||||
class="ml-8"
|
||||
size="small"
|
||||
inline-prompt
|
||||
<el-switch v-model="accessToken.is_active" class="ml-8" size="small" inline-prompt
|
||||
:active-text="$t('views.applicationOverview.appInfo.openText')"
|
||||
:inactive-text="$t('views.applicationOverview.appInfo.closeText')"
|
||||
:before-change="() => changeState(accessToken.is_active)"
|
||||
/>
|
||||
:before-change="() => changeState(accessToken.is_active)" />
|
||||
</div>
|
||||
|
||||
<div class="mt-4 mb-16 url-height flex align-center" style="margin-bottom: 37px">
|
||||
|
|
@ -45,12 +39,7 @@
|
|||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="dark" :content="$t('common.refresh')" placement="top">
|
||||
<el-button
|
||||
@click="refreshAccessToken"
|
||||
type="primary"
|
||||
text
|
||||
style="margin-left: 1px"
|
||||
>
|
||||
<el-button @click="refreshAccessToken" type="primary" text style="margin-left: 1px">
|
||||
<el-icon>
|
||||
<RefreshRight />
|
||||
</el-icon>
|
||||
|
|
@ -58,13 +47,8 @@
|
|||
</el-tooltip>
|
||||
</div>
|
||||
<div>
|
||||
<el-button
|
||||
v-if="accessToken?.is_active"
|
||||
:disabled="!accessToken?.is_active"
|
||||
tag="a"
|
||||
:href="shareUrl"
|
||||
target="_blank"
|
||||
>
|
||||
<el-button v-if="accessToken?.is_active" :disabled="!accessToken?.is_active" tag="a" :href="shareUrl"
|
||||
target="_blank">
|
||||
<AppIcon iconName="app-create-chat" class="mr-4"></AppIcon>
|
||||
{{ $t('views.application.operation.toChat') }}
|
||||
</el-button>
|
||||
|
|
@ -72,11 +56,8 @@
|
|||
<AppIcon iconName="app-create-chat" class="mr-4"></AppIcon>
|
||||
{{ $t('views.application.operation.toChat') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
:disabled="!accessToken?.is_active"
|
||||
@click="openDialog"
|
||||
v-if="permissionPrecise.overview_embed(id)"
|
||||
>
|
||||
<el-button :disabled="!accessToken?.is_active" @click="openDialog"
|
||||
v-if="permissionPrecise.overview_embed(id)">
|
||||
<AppIcon iconName="app-export" class="mr-4"></AppIcon>
|
||||
{{ $t('views.applicationOverview.appInfo.embedInWebsite') }}
|
||||
</el-button>
|
||||
|
|
@ -88,10 +69,7 @@
|
|||
{{ $t('views.applicationOverview.appInfo.accessControl') }}
|
||||
</el-button>
|
||||
<!-- 显示设置 -->
|
||||
<el-button
|
||||
@click="openDisplaySettingDialog"
|
||||
v-if="permissionPrecise.overview_display(id)"
|
||||
>
|
||||
<el-button @click="openDisplaySettingDialog" v-if="permissionPrecise.overview_display(id)">
|
||||
<el-icon class="mr-4">
|
||||
<Setting />
|
||||
</el-icon>
|
||||
|
|
@ -101,19 +79,13 @@
|
|||
</el-col>
|
||||
<el-col :span="12" class="mt-16">
|
||||
<div class="flex">
|
||||
<el-text type="info"
|
||||
>{{ $t('views.applicationOverview.appInfo.apiAccessCredentials') }}
|
||||
<el-text type="info">{{ $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-button
|
||||
type="primary"
|
||||
link
|
||||
@click="toUrl(apiUrl)"
|
||||
class="vertical-middle lighter break-all"
|
||||
>
|
||||
<el-button type="primary" link @click="toUrl(apiUrl)" class="vertical-middle lighter break-all">
|
||||
{{ apiUrl }}
|
||||
</el-button>
|
||||
</div>
|
||||
|
|
@ -124,7 +96,7 @@
|
|||
|
||||
<span class="vertical-middle lighter break-all ellipsis-1">{{
|
||||
baseUrl + id
|
||||
}}</span>
|
||||
}}</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>
|
||||
|
|
@ -133,10 +105,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<el-button
|
||||
@click="openAPIKeyDialog"
|
||||
v-if="permissionPrecise.overview_api_key(id)"
|
||||
>
|
||||
<el-button @click="openAPIKeyDialog" v-if="permissionPrecise.overview_api_key(id)">
|
||||
<el-icon class="mr-4">
|
||||
<Key />
|
||||
</el-icon>
|
||||
|
|
@ -152,29 +121,13 @@
|
|||
{{ $t('views.applicationOverview.monitor.monitoringStatistics') }}
|
||||
</h4>
|
||||
<div class="mb-16">
|
||||
<el-select
|
||||
v-model="history_day"
|
||||
class="mr-12"
|
||||
@change="changeDayHandle"
|
||||
style="width: 180px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in dayOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
<el-select v-model="history_day" class="mr-12" @change="changeDayHandle" style="width: 180px">
|
||||
<el-option v-for="item in dayOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
<el-date-picker
|
||||
v-if="history_day === 'other'"
|
||||
v-model="daterangeValue"
|
||||
type="daterange"
|
||||
<el-date-picker v-if="history_day === 'other'" v-model="daterangeValue" type="daterange"
|
||||
:start-placeholder="$t('views.applicationOverview.monitor.startDatePlaceholder')"
|
||||
:end-placeholder="$t('views.applicationOverview.monitor.endDatePlaceholder')"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
@change="changeDayRangeHandle"
|
||||
/>
|
||||
:end-placeholder="$t('views.applicationOverview.monitor.endDatePlaceholder')" format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD" @change="changeDayRangeHandle" />
|
||||
</div>
|
||||
<div v-loading="statisticsLoading">
|
||||
<StatisticsCharts :data="statisticsData" />
|
||||
|
|
@ -183,11 +136,7 @@
|
|||
</div>
|
||||
</el-scrollbar>
|
||||
|
||||
<EmbedDialog
|
||||
ref="EmbedDialogRef"
|
||||
:data="detail"
|
||||
:api-input-params="mapToUrlParams(apiInputParams)"
|
||||
/>
|
||||
<EmbedDialog ref="EmbedDialogRef" :data="detail" :api-input-params="mapToUrlParams(apiInputParams)" />
|
||||
<APIKeyDialog ref="APIKeyDialogRef" />
|
||||
|
||||
<!-- 社区版访问限制 -->
|
||||
|
|
@ -232,7 +181,7 @@ const {
|
|||
params: { id },
|
||||
} = route as any
|
||||
|
||||
const apiUrl = window.location.origin + '/doc/chat/'
|
||||
const apiUrl = window.location.origin + '/doc_chat/'
|
||||
|
||||
const baseUrl = window.location.origin + `${window.MaxKB.chatPrefix}/api/`
|
||||
|
||||
|
|
@ -373,7 +322,7 @@ function refreshAccessToken() {
|
|||
const str = t('views.applicationOverview.appInfo.refreshToken.refreshSuccess')
|
||||
updateAccessToken(obj, str)
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch(() => { })
|
||||
}
|
||||
|
||||
async function changeState(bool: boolean) {
|
||||
|
|
@ -419,20 +368,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