Bladeren bron

支持大模型接口切换

zhuf 1 jaar geleden
bovenliggende
commit
6c4045b2f5
5 gewijzigde bestanden met toevoegingen van 109 en 28 verwijderingen
  1. 7 0
      .vscode/launch.json
  2. 18 15
      src/components/chat-bot/index.vue
  3. 12 10
      src/components/chat-bot/sdk/chat.ts
  4. 59 0
      src/components/chat-bot/sdk/tti.ts
  5. 13 3
      vite.config.ts

+ 7 - 0
.vscode/launch.json

@@ -0,0 +1,7 @@
+{
+  // 使用 IntelliSense 了解相关属性。 
+  // 悬停以查看现有属性的描述。
+  // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
+  "version": "0.2.0",
+  "configurations": []
+}

+ 18 - 15
src/components/chat-bot/index.vue

@@ -6,7 +6,7 @@ import placeImg from './place.png'
 import { TTSRecorder } from './sdk/chat'
 import { audioPlayer, connectTtsWS } from './sdk/tts'
 import { connectIatWS, iatStatus, recorder } from './sdk/iat'
-import { qa_audio, qa_text } from './qa.ts'
+import { qa_audio, qa_text } from './qa'
 // const anim = ref(null)
 
 // onMounted(() => {
@@ -21,7 +21,9 @@ import { qa_audio, qa_text } from './qa.ts'
 
 const isWorking = ref(false)
 
-const bigModel = $ref(new TTSRecorder())
+const modelVersion = ref('3.1')
+
+let bigModel = $ref(new TTSRecorder({ version: modelVersion.value }))
 
 const videoRef = ref<HTMLVideoElement>()
 const videoLoaded = ref(false)
@@ -203,6 +205,11 @@ function handleStartIat() {
     recorder.stop()
   }
 }
+
+function handleChangeTab() {
+  bigModel.ttsWS?.close()
+  bigModel = new TTSRecorder({ version: modelVersion.value })
+}
 </script>
 
 <template>
@@ -225,6 +232,10 @@ function handleStartIat() {
         />
       </div>
       <div class="w-440px flex flex-col justify-between rounded bg-white px-10px py-10px">
+        <el-tabs v-model="modelVersion" stretch @tab-change="handleChangeTab">
+          <el-tab-pane label="5.0" name="3.1" />
+          <el-tab-pane label="6.0" name="3.5" />
+        </el-tabs>
         <el-scrollbar ref="scrollbarRef" height="680px" class="px-14px">
           <div class="flex flex-col gap-4">
             <div class="rounded-4px bg-hex-f0f0f0 p-14px text-gray-500">
@@ -250,26 +261,18 @@ function handleStartIat() {
           >
             <Microphone class="h-20px w-20px" />
           </div> -->
-          <el-tooltip
-            class=""
-            effect="dark"
-            content="一次语音识别时长不能超过60秒"
-            placement="top-start"
-          >
+          <el-tooltip class="" effect="dark" content="一次语音识别时长不能超过60秒" placement="top-start">
             <el-button
-              :icon="Microphone" circle :color="(iatStatus === 'UNDEFINED' || iatStatus === 'CLOSED') ? '#626aef' : '#f56c6c'"
-              :disabled="isWorking" style="--color: #fff;"
-              @click="handleStartIat"
+              :icon="Microphone" circle
+              :color="(iatStatus === 'UNDEFINED' || iatStatus === 'CLOSED') ? '#626aef' : '#f56c6c'"
+              :disabled="isWorking" style="--color: #fff;" @click="handleStartIat"
             />
           </el-tooltip>
           <el-input
             v-model="questionInput" size="large" type="textarea" placeholder="请输入您的问题"
             :autosize="{ minRows: 1, maxRows: 4 }"
           />
-          <el-button
-            color="#626aef" :disabled="isWorking"
-            @click="handleSendMessage(questionInput, true)"
-          >
+          <el-button color="#626aef" :disabled="isWorking" @click="handleSendMessage(questionInput, true)">
             发送
           </el-button>
         </div>

+ 12 - 10
src/components/chat-bot/sdk/chat.ts

@@ -4,17 +4,19 @@ import { user } from '~/store/index'
 
 let total_res = '' // 保存回答历史
 
-function getWebsocketUrl(): Promise<string> {
+// const version = '3.5'
+
+function getWebsocketUrl(version: string): Promise<string> {
   return new Promise((resolve, reject) => {
     const apiKey = API_KEY
     const apiSecret = API_SECRET
-    let url = 'wss://spark-api.xf-yun.com/v3.1/chat'
+    let url = `wss://spark-api.xf-yun.com/v${version}/chat`
     const host = location.host
     const date = new Date().toGMTString()
     // const date = Date.now()
     const algorithm = 'hmac-sha256'
     const headers = 'host date request-line'
-    const signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v3.1/chat HTTP/1.1`
+    const signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v${version}/chat HTTP/1.1`
     const signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret)
     const signature = CryptoJS.enc.Base64.stringify(signatureSha)
     const authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`
@@ -30,17 +32,17 @@ export class TTSRecorder {
   appId: string
   status: string
   ttsWS?: WebSocket
+  version = '3.1'
   playTimeout: any
   onWillStatusChange?: (oldStatus: string, newStatus: string) => void
   onWillResultChange?: (answerPart: string) => void
   onWillResultFinish?: (answerFull: string) => void
 
-  constructor({
-    appId = APPID,
-  } = {}) {
-    this.appId = appId
+  constructor(args: { version: string }) {
+    this.appId = APPID
     this.status = 'init'
-    console.log('TTSRecorder init')
+    this.version = args.version
+    console.log('TTSRecorder init', this.version)
   }
 
   // 修改状态
@@ -52,14 +54,14 @@ export class TTSRecorder {
   // 连接websocket
   connectChatWS(question: string) {
     this.setStatus('ttsing')
-    return getWebsocketUrl().then((url) => {
+    return getWebsocketUrl(this.version).then((url) => {
       let ttsWS
       if ('WebSocket' in window) {
         this.ttsWS = ttsWS = new WebSocket(url)
         console.log('WebSocket创建成功')
       }
       else if ('MozWebSocket' in window) {
-        // @ts-expect-error
+        // @ts-expect-error MozWebSocket
         this.ttsWS = ttsWS = new MozWebSocket(url)
         console.log('WebSocket创建成功')
       }

+ 59 - 0
src/components/chat-bot/sdk/tti.ts

@@ -0,0 +1,59 @@
+import CryptoJS from 'crypto-js'
+import axios from 'axios'
+import { API_KEY, API_SECRET, APPID } from './secret'
+import { user } from '~/store/index'
+// const total_res = '' // 保存回答历史
+
+function getHttpUrl(): Promise<string> {
+  return new Promise((resolve, reject) => {
+    const apiKey = API_KEY
+    const apiSecret = API_SECRET
+    let url = 'https://spark-api.cn-huabei-1.xf-yun.com/v2.1/tti'
+    const host = location.host
+    // const host = url
+    const date = new Date().toGMTString()
+    // const date = Date.now()
+    const algorithm = 'hmac-sha256'
+    const headers = 'host date request-line'
+    const signatureOrigin = `host: ${host}\ndate: ${date}\nPOST /v2.1/tti HTTP/1.1`
+    const signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret)
+    const signature = CryptoJS.enc.Base64.stringify(signatureSha)
+    const authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`
+    const authorization = btoa(authorizationOrigin)
+    url = `${url}?authorization=${authorization}&date=${date}&host=${host}`
+    // url = `${url}?authorization=${encodeURIComponent(authorization)}&date=${encodeURIComponent(date)}&host=${encodeURIComponent(host)}`
+    console.log('getHttpUrl : ', authorizationOrigin, url)
+    resolve(url)
+  })
+}
+
+export function startTTI() {
+  getHttpUrl().then((url) => {
+    console.log('getHttpUrl : ', url)
+    axios.post(url, {
+      header: {
+        app_id: APPID,
+        uid: user.value?.user_id,
+      },
+      parameter: {
+        chat: {
+          domain: 'general',
+          width: 512,
+          height: 512,
+        },
+      },
+      payload: {
+        message: {
+          text: [
+            {
+              role: 'user',
+              content: '帮我画一座山',
+            },
+          ],
+        },
+      },
+    }).then((res) => {
+      console.log('res : ', res)
+    })
+  })
+}

+ 13 - 3
vite.config.ts

@@ -9,7 +9,8 @@ import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
 import AutoImport from 'unplugin-auto-import/vite'
 import WindiCSS from 'vite-plugin-windicss'
 import VueMacros from 'unplugin-vue-macros/vite'
-import topLevelAwait from "vite-plugin-top-level-await";
+import topLevelAwait from 'vite-plugin-top-level-await'
+
 export default defineConfig({
   resolve: {
     alias: {
@@ -26,9 +27,9 @@ export default defineConfig({
   plugins: [
     topLevelAwait({
       // The export name of top-level await promise for each chunk module
-      promiseExportName: "__tla",
+      promiseExportName: '__tla',
       // The function to generate import names of top-level await promise in each chunk module
-      promiseImportName: i => `__tla_${i}`
+      promiseImportName: i => `__tla_${i}`,
     }),
     VueMacros({
       plugins: {
@@ -83,4 +84,13 @@ export default defineConfig({
   test: {
     environment: 'jsdom',
   },
+  build: {
+    minify: 'terser',
+    terserOptions: {
+      compress: {
+        drop_console: true,
+        drop_debugger: true,
+      },
+    },
+  },
 })