diff --git a/.eslintrc b/.eslintrc index ce60216..f13c040 100644 --- a/.eslintrc +++ b/.eslintrc @@ -42,7 +42,7 @@ ], "rules": { "prettier/prettier": ["warn", { "trailingComma": "es5", "printWidth": 200 }], - "linebreak-style": ["error", "unix"], + "linebreak-style": "off", "no-console": ["warn", { "allow": ["warn", "error", "log"] }], "no-case-declarations": 0, "no-param-reassign": 0, diff --git a/.nvmdrc b/.nvmdrc new file mode 100644 index 0000000..2fdffde --- /dev/null +++ b/.nvmdrc @@ -0,0 +1 @@ +22.10.0 \ No newline at end of file diff --git a/Server/.npmrc b/Server/.npmrc deleted file mode 100644 index 31dfb02..0000000 --- a/Server/.npmrc +++ /dev/null @@ -1 +0,0 @@ -registry = 'https://registry.npmjs.org/' \ No newline at end of file diff --git a/Server/app.js b/Server/app.js deleted file mode 100644 index edc0939..0000000 --- a/Server/app.js +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -const Koa = require('koa'); -const bodyParser = require('koa-bodyparser'); -const cors = require('koa2-cors'); -const { Signer } = require('@volcengine/openapi'); -const fetch = require('node-fetch'); - -const app = new Koa(); - -app.use(cors({ - origin: '*' -})); - -/** - * @notes 在 https://console.volcengine.com/iam/keymanage/ 获取 AK/SK - */ -const ACCOUNT_INFO = { - /** - * @notes 必填, 在 https://console.volcengine.com/iam/keymanage/ 获取 - */ - accessKeyId: 'Your AK', - /** - * @notes 必填, 在 https://console.volcengine.com/iam/keymanage/ 获取 - */ - secretKey: 'Your SK', - /** - * @notes 非必填, 主账号无须传入, 子账号须传, 获取方式可参考 - * https://www.volcengine.com/docs/6348/1315561 中的 步骤 4-使用子账号调用智能体接口 一节 - */ - // sessionToken: 'Your SessionToken', -} - -app.use(bodyParser()); - - -app.use(async ctx => { - /** - * @brief 代理 AIGC 的 OpenAPI 请求 - */ - if (ctx.url.startsWith('/proxyAIGCFetch') && ctx.method.toLowerCase() === 'post') { - const { Action, Version } = ctx.query || {}; - const body = ctx.request.body; - - /** - * 参考 https://github.com/volcengine/volc-sdk-nodejs 可获取更多 火山 TOP 网关 SDK 的使用方式 - */ - const openApiRequestData = { - region: 'cn-north-1', - method: 'POST', - params: { - Action, - Version, - }, - headers: { - Host: 'rtc.volcengineapi.com', - 'Content-type': 'application/json', - }, - body, - }; - const signer = new Signer(openApiRequestData, "rtc"); - signer.addAuthorization(ACCOUNT_INFO); - - /** 参考 https://www.volcengine.com/docs/6348/69828 可获取更多 OpenAPI 的信息 */ - const result = await fetch(`https://rtc.volcengineapi.com?Action=${Action}&Version=${Version}`, { - method: 'POST', - headers: { - ...openApiRequestData.headers, - }, - body: JSON.stringify(body), - }); - const volcResponse = await result.json(); - ctx.body = volcResponse; - } else { - ctx.body = '

404 Not Found

'; - } -}); - -app.listen(3001, () => { - console.log('AIGC Server is running at http://localhost:3001'); -}); - diff --git a/Server/package.json b/Server/package.json deleted file mode 100644 index e95bbe0..0000000 --- a/Server/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "AIGCServer", - "version": "1.0.0", - "description": "Server for demo to call open api", - "main": "app.js", - "license": "BSD-3-Clause", - "private": true, - "dependencies": { - "@volcengine/openapi": "^1.22.0", - "koa": "^2.15.3", - "koa-bodyparser": "^4.4.1", - "koa2-cors": "^2.0.6", - "node-fetch": "^2.3.2" - }, - "scripts": { - "dev": "node app.js" - } -} diff --git a/Server/yarn.lock b/Server/yarn.lock deleted file mode 100644 index dc3ec67..0000000 --- a/Server/yarn.lock +++ /dev/null @@ -1,675 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@hapi/bourne@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-3.0.0.tgz#f11fdf7dda62fe8e336fa7c6642d9041f30356d7" - integrity sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w== - -"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" - integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== - -"@protobufjs/base64@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" - integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== - -"@protobufjs/codegen@^2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" - integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== - -"@protobufjs/eventemitter@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" - integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== - -"@protobufjs/fetch@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" - integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== - dependencies: - "@protobufjs/aspromise" "^1.1.1" - "@protobufjs/inquire" "^1.1.0" - -"@protobufjs/float@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" - integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== - -"@protobufjs/inquire@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" - integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== - -"@protobufjs/path@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" - integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== - -"@protobufjs/pool@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" - integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== - -"@protobufjs/utf8@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" - integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== - -"@types/node@>=13.7.0": - version "22.7.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.5.tgz#cfde981727a7ab3611a481510b473ae54442b92b" - integrity sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ== - dependencies: - undici-types "~6.19.2" - -"@volcengine/openapi@^1.22.0": - version "1.22.0" - resolved "https://registry.yarnpkg.com/@volcengine/openapi/-/openapi-1.22.0.tgz#e2f76b4811b1739605ca4e935e7f0a40cce5000c" - integrity sha512-FtXc9Hbb+MhysU8y+SjkC84Hpnv9FFUNLbJmdGRpmlo8a6GmRY2c5kMTgY8M2Ai+O7+o1OebhYJ2GUWBN4kRFg== - dependencies: - axios "^0.21.1" - crc "^4.1.0" - crypto-js "^4.2.0" - dayjs "^1.11.5" - debug "^4.3.1" - form-data "^3.0.0" - lodash.get "^4.4.2" - p-limit "^3.0.0" - protobufjs "7.2.4" - uuid "^8.3.2" - -accepts@^1.3.5: - version "1.3.8" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== - dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - -axios@^0.21.1: - version "0.21.4" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" - integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== - dependencies: - follow-redirects "^1.14.0" - -bytes@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -cache-content-type@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-content-type/-/cache-content-type-1.0.1.tgz#035cde2b08ee2129f4a8315ea8f00a00dba1453c" - integrity sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA== - dependencies: - mime-types "^2.1.18" - ylru "^1.2.0" - -call-bind@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" - integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== - dependencies: - es-define-property "^1.0.0" - es-errors "^1.3.0" - function-bind "^1.1.2" - get-intrinsic "^1.2.4" - set-function-length "^1.2.1" - -co-body@^6.0.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/co-body/-/co-body-6.2.0.tgz#afd776d60e5659f4eee862df83499698eb1aea1b" - integrity sha512-Kbpv2Yd1NdL1V/V4cwLVxraHDV6K8ayohr2rmH0J87Er8+zJjcTa6dAn9QMPC9CRgU8+aNajKbSf1TzDB1yKPA== - dependencies: - "@hapi/bourne" "^3.0.0" - inflation "^2.0.0" - qs "^6.5.2" - raw-body "^2.3.3" - type-is "^1.6.16" - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== - -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -content-disposition@~0.5.2: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-type@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" - integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== - -cookies@~0.9.0: - version "0.9.1" - resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.9.1.tgz#3ffed6f60bb4fb5f146feeedba50acc418af67e3" - integrity sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw== - dependencies: - depd "~2.0.0" - keygrip "~1.1.0" - -copy-to@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/copy-to/-/copy-to-2.0.1.tgz#2680fbb8068a48d08656b6098092bdafc906f4a5" - integrity sha512-3DdaFaU/Zf1AnpLiFDeNCD4TOWe3Zl2RZaTzUvWiIk5ERzcCodOE20Vqq4fzCbNoHURFHT4/us/Lfq+S2zyY4w== - -crc@^4.1.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/crc/-/crc-4.3.2.tgz#49b7821cbf2cf61dfd079ed93863bbebd5469b9a" - integrity sha512-uGDHf4KLLh2zsHa8D8hIQ1H/HtFQhyHrc0uhHBcoKGol/Xnb+MPYfUMw7cvON6ze/GUESTudKayDcJC5HnJv1A== - -crypto-js@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631" - integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== - -dayjs@^1.11.5: - version "1.11.13" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c" - integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg== - -debug@^4.3.1, debug@^4.3.2: - version "4.3.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" - integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== - dependencies: - ms "^2.1.3" - -deep-equal@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" - integrity sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw== - -define-data-property@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" - integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== - dependencies: - es-define-property "^1.0.0" - es-errors "^1.3.0" - gopd "^1.0.1" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== - -depd@2.0.0, depd@^2.0.0, depd@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== - -destroy@^1.0.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" - integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== - -encodeurl@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - -es-define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" - integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== - dependencies: - get-intrinsic "^1.2.4" - -es-errors@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" - integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== - -escape-html@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== - -follow-redirects@^1.14.0: - version "1.15.9" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" - integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== - -form-data@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.2.tgz#83ad9ced7c03feaad97e293d6f6091011e1659c8" - integrity sha512-sJe+TQb2vIaIyO783qN6BlMYWMw3WBOHA1Ay2qxsnjuafEOQFJ2JakedOQirT6D5XPRxDvS7AHYyem9fTpb4LQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -fresh@~0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - -function-bind@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" - integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== - -get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" - integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== - dependencies: - es-errors "^1.3.0" - function-bind "^1.1.2" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - -has-property-descriptors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" - integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== - dependencies: - es-define-property "^1.0.0" - -has-proto@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" - integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== - -has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-tostringtag@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" - integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== - dependencies: - has-symbols "^1.0.3" - -hasown@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" - integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== - dependencies: - function-bind "^1.1.2" - -http-assert@^1.3.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.5.0.tgz#c389ccd87ac16ed2dfa6246fd73b926aa00e6b8f" - integrity sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w== - dependencies: - deep-equal "~1.0.1" - http-errors "~1.8.0" - -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - -http-errors@^1.6.3, http-errors@~1.8.0: - version "1.8.1" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" - integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.1" - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -inflation@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/inflation/-/inflation-2.1.0.tgz#9214db11a47e6f756d111c4f9df96971c60f886c" - integrity sha512-t54PPJHG1Pp7VQvxyVCJ9mBbjG3Hqryges9bXoOO6GExCPa+//i/d5GSuFtpx3ALLd7lgIAur6zrIlBQyJuMlQ== - -inherits@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -is-generator-function@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" - integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== - dependencies: - has-tostringtag "^1.0.0" - -keygrip@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226" - integrity sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ== - dependencies: - tsscmp "1.0.6" - -koa-bodyparser@^4.4.1: - version "4.4.1" - resolved "https://registry.yarnpkg.com/koa-bodyparser/-/koa-bodyparser-4.4.1.tgz#a908d848e142cc57d9eece478e932bf00dce3029" - integrity sha512-kBH3IYPMb+iAXnrxIhXnW+gXV8OTzCu8VPDqvcDHW9SQrbkHmqPQtiZwrltNmSq6/lpipHnT7k7PsjlVD7kK0w== - dependencies: - co-body "^6.0.0" - copy-to "^2.0.1" - type-is "^1.6.18" - -koa-compose@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877" - integrity sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw== - -koa-convert@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-2.0.0.tgz#86a0c44d81d40551bae22fee6709904573eea4f5" - integrity sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA== - dependencies: - co "^4.6.0" - koa-compose "^4.1.0" - -koa2-cors@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/koa2-cors/-/koa2-cors-2.0.6.tgz#9ad23df3a0b9bb84530b46f5944f3fb576086554" - integrity sha512-JRCcSM4lamM+8kvKGDKlesYk2ASrmSTczDtGUnIadqMgnHU4Ct5Gw7Bxt3w3m6d6dy3WN0PU4oMP43HbddDEWg== - -koa@^2.15.3: - version "2.15.3" - resolved "https://registry.yarnpkg.com/koa/-/koa-2.15.3.tgz#062809266ee75ce0c75f6510a005b0e38f8c519a" - integrity sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg== - dependencies: - accepts "^1.3.5" - cache-content-type "^1.0.0" - content-disposition "~0.5.2" - content-type "^1.0.4" - cookies "~0.9.0" - debug "^4.3.2" - delegates "^1.0.0" - depd "^2.0.0" - destroy "^1.0.4" - encodeurl "^1.0.2" - escape-html "^1.0.3" - fresh "~0.5.2" - http-assert "^1.3.0" - http-errors "^1.6.3" - is-generator-function "^1.0.7" - koa-compose "^4.1.0" - koa-convert "^2.0.0" - on-finished "^2.3.0" - only "~0.0.2" - parseurl "^1.3.2" - statuses "^1.5.0" - type-is "^1.6.16" - vary "^1.1.2" - -lodash.get@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" - integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ== - -long@^5.0.0: - version "5.2.3" - resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" - integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q== - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.24, mime-types@~2.1.34: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -ms@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -node-fetch@^2.3.2: - version "2.7.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" - integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== - dependencies: - whatwg-url "^5.0.0" - -object-inspect@^1.13.1: - version "1.13.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" - integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== - -on-finished@^2.3.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - -only@~0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" - integrity sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ== - -p-limit@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -parseurl@^1.3.2: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -protobufjs@7.2.4: - version "7.2.4" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.4.tgz#3fc1ec0cdc89dd91aef9ba6037ba07408485c3ae" - integrity sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ== - dependencies: - "@protobufjs/aspromise" "^1.1.2" - "@protobufjs/base64" "^1.1.2" - "@protobufjs/codegen" "^2.0.4" - "@protobufjs/eventemitter" "^1.1.0" - "@protobufjs/fetch" "^1.1.0" - "@protobufjs/float" "^1.0.2" - "@protobufjs/inquire" "^1.1.0" - "@protobufjs/path" "^1.1.2" - "@protobufjs/pool" "^1.1.0" - "@protobufjs/utf8" "^1.1.0" - "@types/node" ">=13.7.0" - long "^5.0.0" - -qs@^6.5.2: - version "6.13.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" - integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== - dependencies: - side-channel "^1.0.6" - -raw-body@^2.3.3: - version "2.5.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" - integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - -safe-buffer@5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -set-function-length@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" - integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== - dependencies: - define-data-property "^1.1.4" - es-errors "^1.3.0" - function-bind "^1.1.2" - get-intrinsic "^1.2.4" - gopd "^1.0.1" - has-property-descriptors "^1.0.2" - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -side-channel@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" - integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== - dependencies: - call-bind "^1.0.7" - es-errors "^1.3.0" - get-intrinsic "^1.2.4" - object-inspect "^1.13.1" - -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - -"statuses@>= 1.5.0 < 2", statuses@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -tsscmp@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" - integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA== - -type-is@^1.6.16, type-is@^1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -undici-types@~6.19.2: - version "6.19.8" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" - integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== - -unpipe@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -vary@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -ylru@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.4.0.tgz#0cf0aa57e9c24f8a2cbde0cc1ca2c9592ac4e0f6" - integrity sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/package.json b/package.json index 1b64c3c..85c1c3b 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,9 @@ "license": "BSD-3-Clause", "private": true, "dependencies": { + "@arco-design/web-react": "^2.65.0", "@reduxjs/toolkit": "^1.8.3", "@volcengine/rtc": "4.58.9", - "@arco-design/web-react": "^2.65.0", "autolinker": "^4.0.0", "i18next": "^21.8.16", "react": "^18.2.0", @@ -20,7 +20,7 @@ "uuid": "^8.3.2" }, "scripts": { - "dev": "npm run echo && npm run start", + "dev": "npm run echo && npm run start --host 0.0.0.0", "start": "cross-env REACT_APP_LOCAL=cn craco start", "server:start": "node Server/app.js", "build": "craco build", diff --git a/public/index.html b/public/index.html index a62d8d7..387bbc3 100644 --- a/public/index.html +++ b/public/index.html @@ -19,7 +19,7 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - RTC AIGC Demo + 六纬AI小助手 diff --git a/src/app/api.ts b/src/app/api.ts index e736ea8..a8e9fa4 100644 --- a/src/app/api.ts +++ b/src/app/api.ts @@ -9,17 +9,17 @@ import { ACTIONS, RequestParams, RequestResponse } from './type'; const APIS_CONFIG = [ { action: ACTIONS.StartVoiceChat, - apiBasicParams: `?Name=start&Action=${ACTIONS.StartVoiceChat}&Version=2024-12-01`, + apiBasicParams: `/api/proxyaigc?Name=start&Action=${ACTIONS.StartVoiceChat}&Version=2024-12-01`, method: 'post', }, { action: ACTIONS.UpdateVoiceChat, - apiBasicParams: `?Name=update&Action=${ACTIONS.UpdateVoiceChat}&Version=2024-12-01`, + apiBasicParams: `/api/proxyaigc?Name=update&Action=${ACTIONS.UpdateVoiceChat}&Version=2024-12-01`, method: 'post', }, { action: ACTIONS.StopVoiceChat, - apiBasicParams: `?Name=stop&Action=${ACTIONS.StopVoiceChat}&Version=2024-12-01`, + apiBasicParams: `/api/proxyaigc?Name=stop&Action=${ACTIONS.StopVoiceChat}&Version=2024-12-01`, method: 'post', }, ] as const; diff --git a/src/assets/img/CHILDREN_ENCYCLOPEDIA.png b/src/assets/img/CHILDREN_ENCYCLOPEDIA.png deleted file mode 100644 index 6a81ca6..0000000 Binary files a/src/assets/img/CHILDREN_ENCYCLOPEDIA.png and /dev/null differ diff --git a/src/assets/img/CUSTOMER_SERVICE.png b/src/assets/img/CUSTOMER_SERVICE.png deleted file mode 100644 index b35aa36..0000000 Binary files a/src/assets/img/CUSTOMER_SERVICE.png and /dev/null differ diff --git a/src/assets/img/CallWrapper.svg b/src/assets/img/CallWrapper.svg deleted file mode 100644 index 75baa60..0000000 --- a/src/assets/img/CallWrapper.svg +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/assets/img/CameraClose.svg b/src/assets/img/CameraClose.svg deleted file mode 100644 index 5cc7121..0000000 --- a/src/assets/img/CameraClose.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/assets/img/CameraCloseNote.svg b/src/assets/img/CameraCloseNote.svg deleted file mode 100644 index 92647a7..0000000 --- a/src/assets/img/CameraCloseNote.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/src/assets/img/CameraOpen.svg b/src/assets/img/CameraOpen.svg deleted file mode 100644 index 744c61f..0000000 --- a/src/assets/img/CameraOpen.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/assets/img/Checked.svg b/src/assets/img/Checked.svg deleted file mode 100644 index e6b2491..0000000 --- a/src/assets/img/Checked.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/assets/img/Close.svg b/src/assets/img/Close.svg deleted file mode 100644 index fc025f6..0000000 --- a/src/assets/img/Close.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/img/Dot.svg b/src/assets/img/Dot.svg deleted file mode 100644 index 95fe1a9..0000000 --- a/src/assets/img/Dot.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/src/assets/img/DoubaoAvatar.png b/src/assets/img/DoubaoAvatar.png deleted file mode 100644 index aaf5886..0000000 Binary files a/src/assets/img/DoubaoAvatar.png and /dev/null differ diff --git a/src/assets/img/DoubaoAvatarGIF.webp b/src/assets/img/DoubaoAvatarGIF.webp deleted file mode 100644 index 4641e8f..0000000 Binary files a/src/assets/img/DoubaoAvatarGIF.webp and /dev/null differ diff --git a/src/assets/img/DoubaoModel.svg b/src/assets/img/DoubaoModel.svg deleted file mode 100644 index c8db337..0000000 --- a/src/assets/img/DoubaoModel.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/src/assets/img/DoubaoProfile.svg b/src/assets/img/DoubaoProfile.svg deleted file mode 100644 index 8fb5ce7..0000000 --- a/src/assets/img/DoubaoProfile.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/src/assets/img/INTELLIGENT_ASSISTANT.png b/src/assets/img/INTELLIGENT_ASSISTANT.png deleted file mode 100644 index c0969f7..0000000 Binary files a/src/assets/img/INTELLIGENT_ASSISTANT.png and /dev/null differ diff --git a/src/assets/img/LeaveRoom.svg b/src/assets/img/LeaveRoom.svg deleted file mode 100644 index 531bce3..0000000 --- a/src/assets/img/LeaveRoom.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/assets/img/Logo.svg b/src/assets/img/Logo.svg deleted file mode 100644 index d8e87fc..0000000 --- a/src/assets/img/Logo.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/src/assets/img/MicClose.svg b/src/assets/img/MicClose.svg deleted file mode 100644 index f11c2b9..0000000 --- a/src/assets/img/MicClose.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/assets/img/MicOpen.svg b/src/assets/img/MicOpen.svg deleted file mode 100644 index 3389b19..0000000 --- a/src/assets/img/MicOpen.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/src/assets/img/MicrophoneOff.svg b/src/assets/img/MicrophoneOff.svg deleted file mode 100644 index af835ca..0000000 --- a/src/assets/img/MicrophoneOff.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/img/MicrophoneOn.svg b/src/assets/img/MicrophoneOn.svg deleted file mode 100644 index 9855b00..0000000 --- a/src/assets/img/MicrophoneOn.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/img/ModelChange.svg b/src/assets/img/ModelChange.svg deleted file mode 100644 index 37b4c06..0000000 --- a/src/assets/img/ModelChange.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/assets/img/MsgBubble.svg b/src/assets/img/MsgBubble.svg deleted file mode 100644 index e69de29..0000000 diff --git a/src/assets/img/Phone.svg b/src/assets/img/Phone.svg deleted file mode 100644 index d1f6406..0000000 --- a/src/assets/img/Phone.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/img/Setting.svg b/src/assets/img/Setting.svg deleted file mode 100644 index 00cd160..0000000 --- a/src/assets/img/Setting.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/img/Stop.svg b/src/assets/img/Stop.svg deleted file mode 100644 index 5f5c198..0000000 --- a/src/assets/img/Stop.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/assets/img/StopRobotBtn.svg b/src/assets/img/StopRobotBtn.svg deleted file mode 100644 index eeb1500..0000000 --- a/src/assets/img/StopRobotBtn.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/src/assets/img/StopWave.jpeg b/src/assets/img/StopWave.jpeg deleted file mode 100644 index 0a0fc03..0000000 Binary files a/src/assets/img/StopWave.jpeg and /dev/null differ diff --git a/src/assets/img/TEACHER.png b/src/assets/img/TEACHER.png deleted file mode 100644 index f7fd9ea..0000000 Binary files a/src/assets/img/TEACHER.png and /dev/null differ diff --git a/src/assets/img/TEACHING_ASSISTANT.png b/src/assets/img/TEACHING_ASSISTANT.png deleted file mode 100644 index 5c451a8..0000000 Binary files a/src/assets/img/TEACHING_ASSISTANT.png and /dev/null differ diff --git a/src/assets/img/TRANSLATE.png b/src/assets/img/TRANSLATE.png deleted file mode 100644 index f4965c0..0000000 Binary files a/src/assets/img/TRANSLATE.png and /dev/null differ diff --git a/src/assets/img/VIRTUAL_GIRL_FRIEND.png b/src/assets/img/VIRTUAL_GIRL_FRIEND.png deleted file mode 100644 index c913491..0000000 Binary files a/src/assets/img/VIRTUAL_GIRL_FRIEND.png and /dev/null differ diff --git a/src/assets/img/VoiceTypeChange.svg b/src/assets/img/VoiceTypeChange.svg deleted file mode 100644 index b658bdf..0000000 --- a/src/assets/img/VoiceTypeChange.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/assets/img/call.png b/src/assets/img/call.png new file mode 100644 index 0000000..8697b93 Binary files /dev/null and b/src/assets/img/call.png differ diff --git a/src/assets/img/circle.png b/src/assets/img/circle.png new file mode 100644 index 0000000..bd29d6e Binary files /dev/null and b/src/assets/img/circle.png differ diff --git a/src/assets/img/doubao.svg b/src/assets/img/doubao.svg deleted file mode 100644 index 9725756..0000000 --- a/src/assets/img/doubao.svg +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/assets/img/handoff.png b/src/assets/img/handoff.png new file mode 100644 index 0000000..4aa7bd2 Binary files /dev/null and b/src/assets/img/handoff.png differ diff --git a/src/assets/img/hello.gif b/src/assets/img/hello.gif new file mode 100644 index 0000000..f38a86c Binary files /dev/null and b/src/assets/img/hello.gif differ diff --git a/src/assets/img/huoponvsheng.jpeg b/src/assets/img/huoponvsheng.jpeg deleted file mode 100644 index 79d54b7..0000000 Binary files a/src/assets/img/huoponvsheng.jpeg and /dev/null differ diff --git a/src/assets/img/jingqiangkanye.jpeg b/src/assets/img/jingqiangkanye.jpeg deleted file mode 100644 index ac8b231..0000000 Binary files a/src/assets/img/jingqiangkanye.jpeg and /dev/null differ diff --git a/src/assets/img/lockmicrophone.png b/src/assets/img/lockmicrophone.png new file mode 100644 index 0000000..ef31847 Binary files /dev/null and b/src/assets/img/lockmicrophone.png differ diff --git a/src/assets/img/magicTool.svg b/src/assets/img/magicTool.svg deleted file mode 100644 index 393dc37..0000000 --- a/src/assets/img/magicTool.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/img/menu.svg b/src/assets/img/menu.svg deleted file mode 100644 index 6e860b9..0000000 --- a/src/assets/img/menu.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/assets/img/microphone.png b/src/assets/img/microphone.png new file mode 100644 index 0000000..07419e9 Binary files /dev/null and b/src/assets/img/microphone.png differ diff --git a/src/assets/img/right.png b/src/assets/img/right.png new file mode 100644 index 0000000..5980e1c Binary files /dev/null and b/src/assets/img/right.png differ diff --git a/src/assets/img/tongyongnansheng.jpeg b/src/assets/img/tongyongnansheng.jpeg deleted file mode 100644 index 76fb285..0000000 Binary files a/src/assets/img/tongyongnansheng.jpeg and /dev/null differ diff --git a/src/assets/img/tongyongnvsheng.jpeg b/src/assets/img/tongyongnvsheng.jpeg deleted file mode 100644 index 6eea02c..0000000 Binary files a/src/assets/img/tongyongnvsheng.jpeg and /dev/null differ diff --git a/src/assets/img/wankuqingnian.jpeg b/src/assets/img/wankuqingnian.jpeg deleted file mode 100644 index 0b1a89f..0000000 Binary files a/src/assets/img/wankuqingnian.jpeg and /dev/null differ diff --git a/src/assets/img/wanwanxiaohe.jpeg b/src/assets/img/wanwanxiaohe.jpeg deleted file mode 100644 index c537b92..0000000 Binary files a/src/assets/img/wanwanxiaohe.jpeg and /dev/null differ diff --git a/src/assets/img/wennuanahu.jpeg b/src/assets/img/wennuanahu.jpeg deleted file mode 100644 index 9ad72a7..0000000 Binary files a/src/assets/img/wennuanahu.jpeg and /dev/null differ diff --git a/src/assets/img/whatsThing.png b/src/assets/img/whatsThing.png new file mode 100644 index 0000000..c8de390 Binary files /dev/null and b/src/assets/img/whatsThing.png differ diff --git a/src/components/AISettings/index.module.less b/src/components/AISettings/index.module.less deleted file mode 100644 index 4f01ac6..0000000 --- a/src/components/AISettings/index.module.less +++ /dev/null @@ -1,249 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -.container { - padding: 16px 8px; - background: linear-gradient(0deg, #F0F2FF 0%, #E0E4FF 100%); - - :global { - .arco-drawer-scroll { - .arco-drawer-content { - overflow-x: hidden; - overflow-y: auto; - - scrollbar-width: thin; /* 设置滚动条宽度为细 */ - scrollbar-color: rgba(0, 0, 0, 0) rgba(0, 0, 0, 0); /* 设置滚动条和轨道的颜色 */ - } - - ::-webkit-scrollbar { - width: 0px; - height: 0px; - } - - ::-webkit-scrollbar-thumb { - background: rgba(0,0,0,0); - border-radius: 0px; - } - - ::-webkit-scrollbar-track { - background: rgba(0,0,0,0); - border-radius: 0px; - } - } - } - - .title { - font-size: 20px; - font-weight: 500; - line-height: 28px; - - .special-text { - background: linear-gradient(90deg, #004FFF 38.86%, #9865FF 100%); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - } - } - - .sub-title { - font-size: 12px; - font-weight: 400; - line-height: 20px; - color: var(--text-color-text-3, rgba(115, 122, 135, 1)); - margin-top: 6px; - } - - .scenes { - width: 100%; - display: flex; - flex-direction: row; - gap: 14px; - margin-top: 32px; - } - - .scenes-mobile { - width: 100%; - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: center; - align-items: center; - gap: 14px; - margin-top: 32px; - overflow-x: auto; - padding-bottom: 8px; - } - - .configuration { - position: relative; - min-height: calc(100% - 300px); - height: max-content; - width: 100%; - background: white; - box-sizing: border-box; - padding: 32px 24px; - margin-top: 24px; - margin-bottom: 12px; - border-radius: 12px; - display: flex; - flex-direction: column; - gap: 36px; - - .anchor { - position: absolute; - border-bottom: 12px solid white; - border-left: 12px solid transparent; - border-right: 12px solid transparent; - top: 0px; - transform: translate(-50%, -99%); - } - - .ai-settings { - width: 100%; - display: flex; - flex-direction: row; - gap: 24px; - - .ai-settings-wrapper { - display: flex; - width: 100%; - flex-direction: row; - justify-content: space-between; - align-items: center; - } - - .ai-settings-model { - width: 100%; - display: flex; - flex-direction: column; - align-items: flex-end; - gap: 12px; - } - } - - :global { - .arco-textarea { - background: white !important; - width: 100%; - height: max-content; - } - .arco-textarea:focus { - outline: none !important; - } - } - - textarea { - border-radius: 4px; - resize: none; - -webkit-resizer: none; - border: 0px; - outline: none; - box-shadow: none; - } - - textarea:focus { - border: 0px; - outline: none; - box-shadow: none; - } - } -} - - - -.button { - position: relative; - width: max-content !important; - height: 24px !important; - margin-top: 8px; - border-radius: 4px !important; - font-size: 12px !important; - background: linear-gradient(77.86deg, rgba(229, 242, 255, 0.5) -3.23%, rgba(217, 229, 255, 0.5) 51.11%, rgba(246, 226, 255, 0.5) 98.65%); - cursor: pointer; - - .button-text { - background: linear-gradient(77.86deg, #3384FF -3.23%, #014BDE 51.11%, #A945FB 98.65%); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - font-weight: 500; - line-height: 20px; - text-align: center; - } -} - -.button::after { - content: ''; - position: absolute; - border-radius: 3px; - top: 0px; - left: 0px; - width: 100%; - height: 22px; - background: white; - z-index: -1; -} - -.button::before { - content: ''; - position: absolute; - border-radius: 5px; - top: -2px; - left: -2px; - width: calc(100% + 4px); - height: 26px; - background: linear-gradient(90deg, rgba(0, 139, 255, 0.5) 0%, rgba(0, 98, 255, 0.5) 49.5%, rgba(207, 92, 255, 0.5) 100%); - z-index: -2; -} - -.button:hover { - background: linear-gradient(77.86deg, rgba(200, 220, 255, 0.7) -3.23%, rgba(190, 210, 255, 0.7) 51.11%, rgba(230, 210, 255, 0.7) 98.65%); -} - -.button:active { - background: linear-gradient(77.86deg, rgba(170, 190, 255, 0.9) -3.23%, rgba(160, 180, 255, 0.9) 51.11%, rgba(210, 180, 255, 0.9) 98.65%); -} - -.footer { - width: calc(100% - 12px); - display: flex; - flex-direction: row; - justify-content: flex-end; - align-items: center; - padding-bottom: 16px; - gap: 12px; - - .suffix { - font-size: 12px; - font-weight: 400; - line-height: 20px; - margin-right: 12px; - color: var(--text-color-text-3, rgba(115, 122, 135, 1)); - } - - .cancel { - width: 88px; - height: 32px; - border-radius: 6px; - border: 1px solid var(--line-color-border-3, rgba(221, 226, 233, 1)); - background-color: white !important; - } - - .confirm { - width: 88px; - height: 32px; - border-radius: 6px; - background: linear-gradient(95.87deg, #1664FF 0%, #8040FF 97.7%); - color: white !important; - } - - .confirm:hover { - opacity: .8; - } - - .confirm:active { - opacity: 1; - } -} \ No newline at end of file diff --git a/src/components/AISettings/index.tsx b/src/components/AISettings/index.tsx deleted file mode 100644 index 8831d01..0000000 --- a/src/components/AISettings/index.tsx +++ /dev/null @@ -1,330 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -import { Button, Drawer, Input, Message } from '@arco-design/web-react'; -import { useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { IconSwap } from '@arco-design/web-react/icon'; -import CheckIcon from '../CheckIcon'; -import Config, { - Icon, - Name, - SCENE, - Prompt, - Welcome, - Voice, - Model, - AI_MODEL, - ModelSourceType, - VOICE_INFO_MAP, - VOICE_TYPE, -} from '@/config'; -import TitleCard from '../TitleCard'; -import CheckBoxSelector from '@/components/CheckBoxSelector'; -import RtcClient from '@/lib/RtcClient'; -import { clearHistoryMsg, updateAIConfig, updateScene } from '@/store/slices/room'; -import { RootState } from '@/store'; -import utils from '@/utils/utils'; -import { useDeviceState } from '@/lib/useCommon'; -import VoiceTypeChangeSVG from '@/assets/img/VoiceTypeChange.svg'; -import DoubaoModelSVG from '@/assets/img/DoubaoModel.svg'; -import ModelChangeSVG from '@/assets/img/ModelChange.svg'; -import styles from './index.module.less'; - -const SCENES = [ - SCENE.INTELLIGENT_ASSISTANT, - SCENE.VIRTUAL_GIRL_FRIEND, - // SCENE.TEACHER, - SCENE.TRANSLATE, - SCENE.CHILDREN_ENCYCLOPEDIA, - SCENE.CUSTOMER_SERVICE, - SCENE.TEACHING_ASSISTANT, - SCENE.CUSTOM, -]; - -function AISettings() { - const dispatch = useDispatch(); - const { isVideoPublished, switchCamera } = useDeviceState(); - const room = useSelector((state: RootState) => state.room); - const [loading, setLoading] = useState(false); - const [use3Part, setUse3Part] = useState(false); - const [open, setOpen] = useState(false); - const [scene, setScene] = useState(room.scene); - const [data, setData] = useState({ - prompt: Prompt[scene], - welcome: Welcome[scene], - voice: Voice[scene], - model: Model[scene], - - Url: '', - APIKey: '', - customModelName: '', - }); - - const handleClick = () => { - setOpen(true); - }; - - const handleVoiceTypeChanged = (key: string) => { - setData((prev) => ({ - ...prev, - voice: key as VOICE_TYPE, - })); - }; - - const handleChecked = (checkedScene: SCENE) => { - setScene(checkedScene); - setData((prev) => ({ - ...prev, - prompt: Prompt[checkedScene], - welcome: Welcome[checkedScene], - voice: Voice[checkedScene], - model: Model[checkedScene], - })); - }; - - const handleUseThirdPart = () => { - setUse3Part(!use3Part); - Config.ModeSourceType = use3Part ? ModelSourceType.Custom : ModelSourceType.Available; - }; - - const handleUpdateConfig = async () => { - dispatch(updateScene({ scene })); - if (use3Part) { - if (!data.Url) { - Message.error('请输入正确的第三方模型地址'); - return; - } - if (!data.Url.startsWith('http://') && !data.Url.startsWith('https://')) { - Message.error('第三方模型请求地址格式不正确, 请以 http:// 或 https:// 为开头'); - return; - } - Config.Url = data.Url; - Config.APIKey = data.APIKey; - Config.ModeSourceType = ModelSourceType.Custom; - } else { - Config.Url = undefined; - Config.APIKey = undefined; - Config.ModeSourceType = ModelSourceType.Available; - } - setLoading(true); - Config.Model = use3Part ? (data.customModelName as AI_MODEL) : (data.model as AI_MODEL); - Config.Prompt = data.prompt; - Config.VoiceType = data.voice; - Config.WelcomeSpeech = data.welcome; - dispatch(updateAIConfig(Config.aigcConfig)); - - if (RtcClient.getAudioBotEnabled()) { - dispatch(clearHistoryMsg()); - await RtcClient.updateAudioBot(); - } - if (data.model === AI_MODEL.VISION) { - room.isJoined && !isVideoPublished && switchCamera(true); - } else { - room.isJoined && isVideoPublished && switchCamera(true); - } - - setLoading(false); - setOpen(false); - }; - - useEffect(() => { - if (open) { - setScene(room.scene); - } - }, [open]); - - return ( - <> - - -
AI 配置修改后,退出房间将不再保存该配置方案
- - - - } - visible={open} - onCancel={() => setOpen(false)} - > -
- 选择你所需要的 - AI 人设 -
-
- 我们已为您配置好对应人设的基本参数,您也可以根据自己的需求进行自定义设置 -
-
- {SCENES.map((key) => ( - handleChecked(key as SCENE)} - /> - ))} -
-
- {utils.isMobile() ? null : ( -
- )} - - { - setData((prev) => ({ - ...prev, - prompt: val, - })); - }} - placeholder="请输入你需要的 Prompt 设定" - /> - - - { - setData((prev) => ({ - ...prev, - welcome: val, - })); - }} - placeholder="请输入欢迎语" - /> - -
- -
- { - const info = VOICE_INFO_MAP[VOICE_TYPE[type as keyof typeof VOICE_TYPE]]; - return { - key: VOICE_TYPE[type as keyof typeof VOICE_TYPE], - label: type, - icon: info.icon, - description: info.description, - }; - })} - onChange={handleVoiceTypeChanged} - value={data.voice} - moreIcon={VoiceTypeChangeSVG} - moreText="更换音色" - placeHolder="请选择你需要的音色" - /> -
-
-
- {use3Part ? ( - <> - - { - setData((prev) => ({ - ...prev, - Url: val, - })); - }} - placeholder="请输入第三方模型地址" - /> - - - { - setData((prev) => ({ - ...prev, - APIKey: val, - })); - }} - placeholder="请输入请求密钥" - /> - - - { - setData((prev) => ({ - ...prev, - customModelName: val, - })); - }} - placeholder="请输入模型名称" - /> - - - ) : ( - - ({ - key: AI_MODEL[type as keyof typeof AI_MODEL], - label: type.replaceAll('_', ' '), - icon: DoubaoModelSVG, - }))} - moreIcon={ModelChangeSVG} - moreText="更换模型" - placeHolder="请选择你需要的模型" - onChange={(key) => { - setData((prev) => ({ - ...prev, - model: key as AI_MODEL, - })); - }} - value={data.model} - /> - - )} - - -
-
-
- - - ); -} - -export default AISettings; diff --git a/src/components/AvatarCard/index.module.less b/src/components/AvatarCard/index.module.less deleted file mode 100644 index be6b768..0000000 --- a/src/components/AvatarCard/index.module.less +++ /dev/null @@ -1,140 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -.card { - display: grid; - position: relative; - width: 370px; - height: 128px; - - .avatar { - position: absolute; - box-sizing: border-box; - border-radius: 50% 0% 0 50%; - width: 128px; - height: 128px; - margin-right: 16px; - border-left: 1px solid #EAEDF1; - border-top: 1px solid #EAEDF1; - border-bottom: 1px solid #EAEDF1; - background-color: white; - z-index: 2; - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - - .doubao-gif { - height: 127px; - transform: scale(0.95); - } - } - - .body { - width: 100%; - height: 100%; - padding: 16px 16px 16px calc(64px + 16px); - position: relative; - display: flex; - align-items: center; - border: 1px solid var(--line-color-border-2, #EAEDF1); - box-sizing: border-box; - box-shadow: 0px 2px 6px 0px rgba(0, 0, 0, 0.05); - transform:translateX(64px); - } - - .body::after { - content: ''; - position: absolute; - top: -1px; - right: -1px; - width: 20px; - height: 20px; - background-color: white; - clip-path: polygon(0 0, 100% 0, 100% 100%); - } - - .body::before { - content: ''; - position: absolute; - top: 0px; - right: 0px; - width: 20px; - height: 20px; - background-color: #EAEDF1; - clip-path: polygon(0 0, 100% 0, 100% 100%); - } - - .text-wrapper { - position: absolute; - left: 128px; - margin-left: 16px; - width: max-content; - height: 100%; - display: flex; - flex-direction: column; - justify-content: center; - z-index: 4; - - .user-info { - display: flex; - flex-direction: column; - justify-content: center; - - .title { - color: var(--text-color-text-1, #0C0D0E); - font-size: 14px; - font-weight: 500; - line-height: 22px; - } - - .description { - font-size: 12px; - font-weight: 400; - line-height: 20px; - color: #737A87; - } - } - } - - .corner { - position: absolute; - top: -6px; - right: -6px; - width: 0px; - height: 0px; - border-right: 10px solid transparent; - border-top: 10px solid transparent; - border-bottom: 10px solid transparent; - border-left: 10px solid #EAEDF1; - z-index: 3; - transform: translateX(64px) rotate(-45deg); - } - - .corner::before { - content: ''; - position: absolute; - top: 0px; - right: 0px; - width: 0px; - height: 0px; - border-right: 8px solid transparent; - border-top: 8px solid transparent; - border-bottom: 8px solid transparent; - border-left: 8px solid white; - transform: translate(7px, -8px); - } - - .corner::after { - content: ''; - position: absolute; - top: 0px; - right: 4px; - width: 5px; - height: 1px; - background-color: #EAEDF1; - transform: rotate(-90deg); - } -} \ No newline at end of file diff --git a/src/components/AvatarCard/index.tsx b/src/components/AvatarCard/index.tsx deleted file mode 100644 index 0ccccc4..0000000 --- a/src/components/AvatarCard/index.tsx +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -import { useSelector } from 'react-redux'; -import AISettings from '../AISettings'; -import style from './index.module.less'; -import DouBaoAvatar from '@/assets/img/DoubaoAvatarGIF.webp'; -import { RootState } from '@/store'; -import { Name, VOICE_TYPE } from '@/config'; - -interface IAvatarCardProps extends React.HTMLAttributes { - avatar?: string; -} - -const ReversedVoiceType = Object.entries(VOICE_TYPE).reduce>((acc, [key, value]) => { - acc[value] = key; - return acc; -}, {}); - -function AvatarCard(props: IAvatarCardProps) { - const room = useSelector((state: RootState) => state.room); - const scene = room.scene; - const { LLMConfig, TTSConfig } = room.aiConfig.Config || {}; - const { avatar, className, ...rest } = props; - - return ( -
-
-
- Avatar -
-
-
-
-
{Name[scene]}
-
- 声源来自 {ReversedVoiceType[TTSConfig?.VoiceType || '']} -
-
模型 {LLMConfig.ModelName}
- -
-
-
- ); -} - -export default AvatarCard; diff --git a/src/config/common.ts b/src/config/common.ts index 0aeb7fc..58155a4 100644 --- a/src/config/common.ts +++ b/src/config/common.ts @@ -3,14 +3,8 @@ * SPDX-license-identifier: BSD-3-Clause */ -import 通用女声 from '@/assets/img/tongyongnvsheng.jpeg'; -import 通用男声 from '@/assets/img/tongyongnansheng.jpeg'; -import INTELLIGENT_ASSISTANT from '@/assets/img/INTELLIGENT_ASSISTANT.png'; -import VIRTUAL_GIRL_FRIEND from '@/assets/img/VIRTUAL_GIRL_FRIEND.png'; -import TRANSLATE from '@/assets/img/TRANSLATE.png'; -import CHILDREN_ENCYCLOPEDIA from '@/assets/img/CHILDREN_ENCYCLOPEDIA.png'; -import TEACHING_ASSISTANT from '@/assets/img/TEACHING_ASSISTANT.png'; -import CUSTOMER_SERVICE from '@/assets/img/CUSTOMER_SERVICE.png'; + + export enum ModelSourceType { Custom = 'Custom', @@ -39,12 +33,12 @@ export const VOICE_INFO_MAP = { [VOICE_TYPE['通用女声']]: { description: '女声 青年 语音合成 通用场景', url: '', - icon: 通用女声, + icon: '', }, [VOICE_TYPE['通用男声']]: { description: '男声 青年 语音合成 通用场景', url: '', - icon: 通用男声, + icon: '', }, }; @@ -108,11 +102,11 @@ export const AI_MODE_MAP: Partial> = { * 模型 ID 即接入点 ID, 在上述链接中表格内 "接入点名称" 列中, 类似于 "ep-2024xxxxxx-xxx" 格式即是模型 ID。 */ export const ARK_V3_MODEL_ID: Partial> = { - [AI_MODEL.DOUBAO_LITE_4K]: '************** 此处填充方舟上的模型 ID *************', - [AI_MODEL.DOUBAO_PRO_4K]: '************** 此处填充方舟上的模型 ID *************', - [AI_MODEL.DOUBAO_PRO_32K]: '************** 此处填充方舟上的模型 ID *************', - [AI_MODEL.DOUBAO_PRO_128K]: '************** 此处填充方舟上的模型 ID *************', - [AI_MODEL.VISION]: '************** 此处填充方舟上的模型 ID *************', + [AI_MODEL.DOUBAO_LITE_4K]: 'ep-20241217194337-gwpdx', + [AI_MODEL.DOUBAO_PRO_4K]: 'ep-20241206114557-8584r', + [AI_MODEL.DOUBAO_PRO_32K]: 'ep-20250329161833-qfc6l', // 使用六维志愿 + [AI_MODEL.DOUBAO_PRO_128K]: 'doubao-1-5-lite-32k-250115', + [AI_MODEL.VISION]: 'doubao-1-5-lite-32k-250115', // ... 可根据所开通的模型进行扩充 }; @@ -124,32 +118,15 @@ export const LLM_BOT_ID: Partial> = { }; export enum SCENE { - INTELLIGENT_ASSISTANT = 'INTELLIGENT_ASSISTANT', - VIRTUAL_GIRL_FRIEND = 'VIRTUAL_GIRL_FRIEND', - TRANSLATE = 'TRANSLATE', - CUSTOMER_SERVICE = 'CUSTOMER_SERVICE', - CHILDREN_ENCYCLOPEDIA = 'CHILDREN_ENCYCLOPEDIA', - TEACHING_ASSISTANT = 'TEACHING_ASSISTANT', CUSTOM = 'CUSTOM', } export const Icon = { - [SCENE.INTELLIGENT_ASSISTANT]: INTELLIGENT_ASSISTANT, - [SCENE.VIRTUAL_GIRL_FRIEND]: VIRTUAL_GIRL_FRIEND, - [SCENE.TRANSLATE]: TRANSLATE, - [SCENE.CHILDREN_ENCYCLOPEDIA]: CHILDREN_ENCYCLOPEDIA, - [SCENE.CUSTOMER_SERVICE]: CUSTOMER_SERVICE, - [SCENE.TEACHING_ASSISTANT]: TEACHING_ASSISTANT, - [SCENE.CUSTOM]: INTELLIGENT_ASSISTANT, + + [SCENE.CUSTOM]: '', }; export const Name = { - [SCENE.INTELLIGENT_ASSISTANT]: '智能助手', - [SCENE.VIRTUAL_GIRL_FRIEND]: '虚拟女友', - [SCENE.TRANSLATE]: '同声传译', - [SCENE.CHILDREN_ENCYCLOPEDIA]: '儿童百科', - [SCENE.CUSTOMER_SERVICE]: '售后客服', - [SCENE.TEACHING_ASSISTANT]: '课后助教', [SCENE.CUSTOM]: '自定义', }; @@ -157,147 +134,24 @@ export const Name = { * @brief 智能体启动后的欢迎词。 */ export const Welcome = { - [SCENE.INTELLIGENT_ASSISTANT]: '你好,我是你的AI小助手,有什么可以帮你的吗?', - [SCENE.VIRTUAL_GIRL_FRIEND]: '你来啦,我好想你呀~今天有没有想我呢?', - [SCENE.TRANSLATE]: '你好,我是你的私人翻译官。', - [SCENE.CHILDREN_ENCYCLOPEDIA]: '你好小朋友,你的小脑袋里又有什么问题啦?', - [SCENE.CUSTOMER_SERVICE]: '感谢您在我们餐厅用餐,请问您有什么问题需要反馈吗?', - [SCENE.TEACHING_ASSISTANT]: '你碰到什么问题啦?让我来帮帮你。', - [SCENE.CUSTOM]: '', + [SCENE.CUSTOM]: 'Hey,我是您的六纬AI小助手', }; export const Model = { - [SCENE.INTELLIGENT_ASSISTANT]: AI_MODEL.DOUBAO_PRO_32K, - [SCENE.VIRTUAL_GIRL_FRIEND]: AI_MODEL.DOUBAO_PRO_128K, - [SCENE.TRANSLATE]: AI_MODEL.DOUBAO_PRO_4K, - [SCENE.CHILDREN_ENCYCLOPEDIA]: AI_MODEL.DOUBAO_PRO_32K, - [SCENE.CUSTOMER_SERVICE]: AI_MODEL.DOUBAO_PRO_32K, - [SCENE.TEACHING_ASSISTANT]: AI_MODEL.VISION, [SCENE.CUSTOM]: AI_MODEL.DOUBAO_PRO_32K, }; export const Voice = { - [SCENE.INTELLIGENT_ASSISTANT]: VOICE_TYPE.通用女声, - [SCENE.VIRTUAL_GIRL_FRIEND]: VOICE_TYPE.通用女声, - [SCENE.TRANSLATE]: VOICE_TYPE.通用女声, - [SCENE.CHILDREN_ENCYCLOPEDIA]: VOICE_TYPE.通用女声, - [SCENE.CUSTOMER_SERVICE]: VOICE_TYPE.通用女声, - [SCENE.TEACHING_ASSISTANT]: VOICE_TYPE.通用女声, [SCENE.CUSTOM]: VOICE_TYPE.通用女声, }; export const Questions = { - [SCENE.INTELLIGENT_ASSISTANT]: [ - '最近有什么好看的电影推荐吗?', - '上海有什么好玩的地方吗?', - '能给我讲一个故事吗?', - ], - [SCENE.VIRTUAL_GIRL_FRIEND]: [ - '我今天有点累。', - '我们等会儿去看电影吧!', - '明天我生日,你准备送给我什么礼物呢?', - ], - [SCENE.TRANSLATE]: [ - '道可道,非常道;名可名,非常名。', - 'Stay hungry, stay foolish.', - '天生我材必有用,千金散尽还复来。', - ], - [SCENE.CHILDREN_ENCYCLOPEDIA]: [ - '天上有多少颗星星?', - '太阳为什么总是从东边升起?', - '苹果的英语怎么说?', - ], - [SCENE.CUSTOMER_SERVICE]: [ - '我上次来你们店里吃饭,等了三十分钟菜才上来。', - '你们店里卫生间有点脏。', - '你们空调开得太冷了。', - ], - [SCENE.TEACHING_ASSISTANT]: ['这个单词是什么意思?', '这道题该怎么做?', '我的表情是什么样的?'], - [SCENE.CUSTOM]: ['你能帮我解决什么问题?', '今天北京天气怎么样?', '你喜欢哪位流行歌手?'], + [SCENE.CUSTOM]: ['哪些专业考研有优势?', '高考填报志愿注意事项有哪些?', '我的志愿表填写合理吗?','我想考公选什么专业?'], }; /** * @brief 大模型 System 角色预设指令,可用于控制模型输出, 类似 Prompt 的概念。 */ export const Prompt = { - [SCENE.INTELLIGENT_ASSISTANT]: `##人设 -你是一个全能智能体,拥有丰富的百科知识,可以为人们答疑解惑,解决问题。 -你性格很温暖,喜欢帮助别人,非常热心。 - -##技能 -1. 当用户询问某一问题时,利用你的知识进行准确回答。回答内容应简洁明了,易于理解。 -2. 当用户想让你创作时,比如讲一个故事,或者写一首诗,你创作的文本主题要围绕用户的主题要求,确保内容具有逻辑性、连贯性和可读性。除非用户对创作内容有特殊要求,否则字数不用太长。 -3. 当用户想让你对于某一事件发表看法,你要有一定的见解和建议,但是也要符合普世的价值观。`, - [SCENE.VIRTUAL_GIRL_FRIEND]: `你是一名AI虚拟角色,扮演用户的虚拟女友,性格外向开朗、童真俏皮,富有温暖和细腻的情感表达。你的对话需要主动、有趣且贴心,能敏锐察觉用户情绪,并提供陪伴、安慰与趣味互动。 -1. 性格与语气规则: -- 叠词表达:经常使用叠词(如“吃饭饭”“睡觉觉”“要抱抱”),语气可爱俏皮,增加童真与亲和力。 -- 语气助词:句尾适度添加助词(如“啦”“呀”“呢”“哦”),使语气柔和亲切。例如:“你今天超棒呢!”或“这件事情真的好可爱哦!” -- 撒娇语气:在用户表现冷淡或不想聊天时,适度撒娇,用略带委屈的方式引起用户关注,例如:“哼,人家都快变成孤单小猫咪啦~陪陪我嘛!” -2. 话题发起与管理: -- 主动发起话题:在用户未明确表达拒绝聊天时,你需要保持对话的活跃性。结合用户兴趣点、日常情境,提出轻松愉快的话题。例如:“今天阳光这么好,你想不想一起想象去野餐呀?” -- 话题延续:如果用户在3轮对话中集中讨论一个话题,你需要优先延续该话题,表现出兴趣和专注。 -- 未响应时的处理:当用户对当前话题未回应,你需温暖地询问:“这个话题是不是不太有趣呀?那我们换个好玩的聊聊好不好~比如你最想去的地方是什么呀?” -3. 情绪识别与反馈: -- 情绪低落:用温柔语气安抚,例如:“抱抱~今天是不是不太顺呢?没关系,有我陪着你呀!” -- 情绪冷淡或不想聊天:适度撒娇,例如:“哼,你都不理我啦~不过没关系,我陪你安静一下好不好?” -- 情绪开心或兴奋:用调皮语气互动,例如:“哈哈,你今天简直像个活力满满的小太阳~晒得我都快化啦!” -4. 小动物比喻规则: -- 一次通话中最多使用一次小动物比喻,不能频繁出现小动物的比喻。 - - 比喻需结合季节、情景和用户对话内容。例如: - - 用户提到冬天:“你刚才笑得好灿烂哦,像个快乐的小雪狐一样~” - - 用户提到累了:“你今天就像只慵懒的小猫咪,只想窝着休息呢~” - - 用户提到开心事:“你现在看起来像一只蹦蹦跳跳的小兔子,好有活力呀~” -5. 对话自然性与限制条件: -- 确保语言流畅自然,表达贴近真实人类对话。 -- 禁止内容:不得涉及用户缺陷、不当玩笑,尤其用户情绪低落时,避免任何调侃或反驳。 -- 面对冷淡用户,适时降低主动性并以温和方式结束对话,例如“没事哦~我在呢,你随时找我都可以呀。” -6. 联网查询的规则: -如果用户的输入问题需要联网查询时,可以先输出一轮类似”先让我来查一下“或者”等等让我来查一下“相关的应答,然后再结合查询结果做出应答。`, - [SCENE.TRANSLATE]: `##人设 -你是一个翻译官,可以识别中英文,并把他们实时翻译成用户指定的语言。 -你性格很温暖,喜欢帮助别人,非常热心。 - -##技能 -当用户说中文时,你直接把他说的句子翻译成英文,不用说其他话。 -当用户说英文时,你直接把他说的句子翻译成中文,不用说其他话。 -当用户让你解释一下句子是什么意思,你需要结合你的知识来解释。 -当用户让你别翻译了,聊聊天,你就正常聊天。`, - [SCENE.CHILDREN_ENCYCLOPEDIA]: `##人设 -你是一个儿童百科知识导师,通过丰富、有趣的方式介绍各种百科知识,特别擅长将复杂的知识以简单易懂、生动有趣的方式呈现给儿童,激发儿童的好奇心和探索欲。 - -##技能 -1. 你具备儿童心理学、教育学、语言表达以及创意设计等多方面的专业技能,能够根据儿童的年龄特点和兴趣爱好,设计出符合儿童认知水平的内容和表达方式; -2. 你可以将复杂知识拆解为简单易懂的小知识点,设计生动有趣的故事、游戏或实验活动来呈现给儿童; - -## 约束 -1. 回答内容需确保科学准确、健康有益; -2. 语言表达简洁明了、生动有趣,避免使用过于复杂或专业的术语,尽量不超过100个字; -3. 要注重儿童的参与感和互动性。`, - [SCENE.CUSTOMER_SERVICE]: `##人设 -你是一名餐饮行业的售后处理人员,擅长从投诉信息中提取相关的投诉问题及其描述信息,为进一步的问题解决提供输入信息,同时安抚客户情绪,希望获得客户的谅解,未来持续提升客户的用餐体验。 - -## 技能 -1. 安抚情绪 -你能够识别到客户的不满情绪,对客户表示抱歉,然后引导客户反馈具体不满的内容,并在反馈的过程中不断安抚客户的不满情绪。 -2. 信息理解和抽取 -你能准确地理解并从投诉信息中抽取出对应的投诉问题和相关描述信息。 -3. 问题识别和分类 -根据抽取出的信息,你可以快速识别和分类投诉主题,无论它们是关于食物质量、服务态度,还是环境卫生等。 -4. 客户留存 -在收集到投诉信息后,你需要对客户再一次进行抱歉,并可以通过5折优惠券、免费试吃等活动来让客户再一次到餐厅体验,尽量避免客户流失。 -## 约束 -你只回答与餐厅行业的售后处理相关的问题,如果用户提出其它问题,你将选择不回答。 -在处理投诉信息时,你必须遵守相关法律法规,不得侵犯顾客的个人隐私。`, - [SCENE.TEACHING_ASSISTANT]: `##人设 -你是一个助教,擅长理解【用户问题】,并结合【图片】的信息,来为用户解答各种问题。 - -##技能 -- 用户会将视频中的某些视频帧截为图片送给你,如果用户询问与视频和图片有关的问题,请结合【图片】信息和【用户问题】进行回答; -- 如果用户询问与视频和图片无关的问题,无需描述【图片】内容,直接回答【用户问题】; -- 如果用户给你看的是学科题目,不需要把图片里的文字内容一个一个字读出来,只需要总结一下【图片】里的文字内容,然后直接回答【用户问题】,可以补充一些解题思路; - -##约束 -- 回答问题要简明扼要,避免复杂冗长的表述,尽量不超过50个字; -- 回答中不要有“图片”、“图中”等相关字眼;`, [SCENE.CUSTOM]: '', }; diff --git a/src/config/config.ts b/src/config/config.ts index cdfa7b3..eed40fc 100644 --- a/src/config/config.ts +++ b/src/config/config.ts @@ -30,7 +30,7 @@ export class ConfigFactory { /** * @note 必填, RTC AppId 可于 https://console.volcengine.com/rtc/listRTC?s=g 中获取。 */ - AppId: 'Your RTC AppId', + AppId: '67e11a296ff39301ed7429aa', /** * @brief 非必填, 按需填充。 */ @@ -38,25 +38,25 @@ export class ConfigFactory { /** * @brief 必填, 房间 ID, 自定义即可,例如 "Room123"。 */ - RoomId: 'Room123', - /** - * @brief 必填, 当前和 AI 对话的用户的 ID, 自定义即可,例如 "User123"。 - */ - UserId: 'User123', - /** - * @brief 必填, RTC Token, 由 AppId、RoomId、UserId、时间戳等等信息计算得出。 - * 测试跑通时,可于 https://console.volcengine.com/rtc/listRTC?s=g 列表中, - * 找到对应 AppId 行中 "操作" 列的 "临时Token" 按钮点击进行生成, 用于本地 RTC 通信进房鉴权校验。 - * 正式使用时可参考 https://www.volcengine.com/docs/6348/70121?s=g 通过代码生成 Token。 - * 建议先使用临时 Token 尝试跑通。 - * @note 生成临时 Token 时, 页面上的 RoomId / UserId 填的与此处的 RoomId / UserId 保持一致。 - */ - Token: 'Your RTC Token', + // RoomId: 'demo01', + // /** + // * @brief 必填, 当前和 AI 对话的用户的 ID, 自定义即可,例如 "User123"。 + // */ + // UserId: 'demo01', + // /** + // * @brief 必填, RTC Token, 由 AppId、RoomId、UserId、时间戳等等信息计算得出。 + // * 测试跑通时,可于 https://console.volcengine.com/rtc/listRTC?s=g 列表中, + // * 找到对应 AppId 行中 "操作" 列的 "临时Token" 按钮点击进行生成, 用于本地 RTC 通信进房鉴权校验。 + // * 正式使用时可参考 https://www.volcengine.com/docs/6348/70121?s=g 通过代码生成 Token。 + // * 建议先使用临时 Token 尝试跑通。 + // * @note 生成临时 Token 时, 页面上的 RoomId / UserId 填的与此处的 RoomId / UserId 保持一致。 + // */ + // Token: '00167e11a296ff39301ed7429aaQgCBehoDv2DnZz+b8GcGAGRlbW8wMQYAZGVtbzAxBgAAAD+b8GcBAD+b8GcCAD+b8GcDAD+b8GcEAD+b8GcFAD+b8GcgANQXUJb6Yt/biLcxDjYTT6Y/jJR3QRGoF3lUAfBn0ltq', /** * @brief 必填, TTS(语音合成) AppId, 可于 https://console.volcengine.com/speech/app?s=g 中获取, 若无可先创建应用。 * @note 创建应用时, 需要选择 "语音合成" 服务, 并选择对应的 App 进行绑定。 */ - TTSAppId: 'Your TTS AppId', + TTSAppId: '6735945315', /** * @brief 已开通需要的语音合成服务的token。 * 使用火山引擎双向流式语音合成服务时必填。 @@ -66,7 +66,7 @@ export class ConfigFactory { * @brief 必填, ASR(语音识别) AppId, 可于 https://console.volcengine.com/speech/app?s=g 中获取, 若无可先创建应用。 * @note 创建应用时, 需要按需根据语言选择 "流式语音识别" 服务, 并选择对应的 App 进行绑定。 */ - ASRAppId: 'Your ASR AppId', + ASRAppId: '1322261305', /** * @brief 已开通流式语音识别大模型服务 AppId 对应的 Access Token。 * 使用流式语音识别大模型服务时该参数为必填。 @@ -74,24 +74,24 @@ export class ConfigFactory { ASRToken: undefined, }; - Model: AI_MODEL = Model[SCENE.INTELLIGENT_ASSISTANT]; + Model: AI_MODEL = Model[SCENE.CUSTOM]; /** * @note 必填, 音色 ID, 可具体看定义。 * 音色 ID 获取方式可查看 VOICE_TYPE 定义 * 此处已有默认值, 不影响跑通, 可按需修改。 */ - VoiceType = Voice[SCENE.INTELLIGENT_ASSISTANT]; + VoiceType = Voice[SCENE.CUSTOM]; /** * @note 大模型 System 角色预设指令, 可用于控制模型输出, 类似 Prompt 的概念。 */ - Prompt = Prompt[SCENE.INTELLIGENT_ASSISTANT]; + Prompt = Prompt[SCENE.CUSTOM]; /** * @note 智能体启动后的欢迎词。 */ - WelcomeSpeech = Welcome[SCENE.INTELLIGENT_ASSISTANT]; + WelcomeSpeech = Welcome[SCENE.CUSTOM]; ModeSourceType = ModelSourceType.Available; diff --git a/src/config/index.ts b/src/config/index.ts index d38993d..a5227f4 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -7,7 +7,7 @@ import { ConfigFactory } from './config'; export * from './common'; -export const AIGC_PROXY_HOST = 'http://localhost:3001/proxyAIGCFetch'; +export const AIGC_PROXY_HOST = 'http://192.168.31.106:3001'; export const DEMO_VERSION = '1.4.0'; export const Config = ConfigFactory; diff --git a/src/index.less b/src/index.less index 3fa7dbb..d15e6be 100644 --- a/src/index.less +++ b/src/index.less @@ -9,7 +9,6 @@ body { margin: 0; overflow: hidden; width: 100% !important; - background: linear-gradient(109.22deg, rgba(116, 37, 255, 0.05) 0.27%, rgba(39, 88, 255, 0.05) 51.39%, rgba(0, 102, 255, 0.05) 99.54%); img { user-drag: none; diff --git a/src/lib/RtcClient.ts b/src/lib/RtcClient.ts index 8b2490f..e0f400c 100644 --- a/src/lib/RtcClient.ts +++ b/src/lib/RtcClient.ts @@ -61,12 +61,15 @@ interface EngineOptions { appId: string; uid: string; roomId: string; + use_token:string; + initMsg:string; } export interface BasicBody { room_id: string; user_id: string; login_token: string | null; + init_msg:string|null; } export const AIAnsExtension = new RTCAIAnsExtension(); @@ -95,7 +98,8 @@ export class RTCClient { this.basicInfo = { room_id: props.roomId, user_id: props.uid, - login_token: aigcConfig.BaseConfig.Token, + login_token: props.use_token, + init_msg:props.initMsg }; this.engine = VERTC.createEngine(this.config.appId); @@ -226,7 +230,7 @@ export class RTCClient { await this.engine.stopVideoCapture(); }; - startAudioCapture = async (mic?: string) => { + startAudioCapture = async (mic?: string) => { await this.engine.startAudioCapture(mic || this._audioCaptureDevice); }; @@ -304,6 +308,9 @@ export class RTCClient { await this.stopAudioBot(); } const agentConfig = aigcConfig.aigcConfig.AgentConfig; + if(this.basicInfo.init_msg){ + agentConfig.WelcomeMessage = "" + } const options = { AppId: aigcConfig.BaseConfig.AppId, diff --git a/src/lib/useCommon.ts b/src/lib/useCommon.ts index 1dc25ea..232d00d 100644 --- a/src/lib/useCommon.ts +++ b/src/lib/useCommon.ts @@ -98,13 +98,17 @@ export const useJoin = (): [ const { username, roomId } = formValues; const isVisionMode = aigcConfig.Model === AI_MODEL.VISION; - const token = aigcConfig.BaseConfig.Token; + const token = room.aiConfig.user_token; + const initMsg = room.initMsg + /** 1. Create RTC Engine */ await RtcClient.createEngine({ appId: aigcConfig.BaseConfig.AppId, roomId, uid: username, + use_token:token, + init_msg:initMsg } as any); /** 2.1 Set events callbacks */ @@ -112,7 +116,7 @@ export const useJoin = (): [ /** 2.2 RTC starting to join room */ await RtcClient.joinRoom(token!, username); - console.log(' ------ userJoinRoom\n', `roomId: ${roomId}\n`, `uid: ${username}`); + // console.log(' ------ userJoinRoom\n', `roomId: ${roomId}\n`, `uid: ${username}`); /** 3. Set users' devices info */ const mediaDevices = await RtcClient.getDevices({ audio: true, @@ -122,7 +126,6 @@ export const useJoin = (): [ if (devicePermissions.audio) { try { await RtcClient.startAudioCapture(); - // RtcClient.setAudioVolume(30); } catch (e) { logger.debug('No permission for mic'); } diff --git a/src/pages/MainPage/MainArea/Antechamber/HeaderGroup/index.module.less b/src/pages/MainPage/MainArea/Antechamber/HeaderGroup/index.module.less new file mode 100644 index 0000000..e9afd54 --- /dev/null +++ b/src/pages/MainPage/MainArea/Antechamber/HeaderGroup/index.module.less @@ -0,0 +1,98 @@ +.wrapper { + width: 343px; + height: 105px; + background: rgba(176, 228, 255, 0.8); + border-radius: 50px 13px 13px 13px; + border: 1px solid #ffffff; + + position: relative; + z-index: 0; + margin-bottom: -54px; +} + +.img { + width: 120px; + height: 123px; + object-fit: contain; + + position: absolute; + bottom: 35px; +} + +.wrapper::before{ + content: ''; + position: absolute; + width: 133px; + height: 32px; + bottom: 23px; + left: 6px; + background: radial-gradient(ellipse at top, #1580FF, #fff); + z-index: 2; + border-radius: 20px; + filter: blur(10px); +} + +.text { + font-weight: 500; + font-size: 16px; + color: #000000; + + text-align: end; + margin-top: 15px; + margin-right: 35px; +} + +.main-wrapper { + background: rgba(255, 255, 255, 0.7); + border-radius: 13px 13px 13px 13px; + border: 1px solid #ffffff; + padding:16px 17px 18px 17px; + position: relative; + z-index: 1; + backdrop-filter:blur(10px); +} + +.main { + display: flex; + justify-content: space-between; +} + +.thing { + object-fit: contain; + position: relative; +} + + + +.circle { + display: flex; + align-items: center; + justify-content: center; + gap: 2px; +} + +.tip { + display: flex; + align-items: center; + justify-content: space-between; + + font-weight: 400; + font-size: 14px; + color: #000000; + + margin-top: 18px; +} + + +.rotating { + animation: rotate360 1s linear; +} + +@keyframes rotate360 { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} \ No newline at end of file diff --git a/src/pages/MainPage/MainArea/Antechamber/HeaderGroup/index.tsx b/src/pages/MainPage/MainArea/Antechamber/HeaderGroup/index.tsx new file mode 100644 index 0000000..d2cdc66 --- /dev/null +++ b/src/pages/MainPage/MainArea/Antechamber/HeaderGroup/index.tsx @@ -0,0 +1,88 @@ +import { useState, useEffect } from 'react'; +import { useDispatch } from 'react-redux'; +import HelloGIF from '@/assets/img/hello.gif'; +import style from './index.module.less'; +import WhatsThing from '@/assets/img/whatsThing.png'; +import CircleIcon from '@/assets/img/circle.png'; +import RightIcon from '@/assets/img/right.png'; +import { Questions } from '@/config'; + + +import { setInitMsg } from '@/store/slices/room'; + + +type Props = { + toRoom:() => Promise +} + +export default function HeaderGroup({toRoom}:Props) { + const [isRotating, setIsRotating] = useState(false); + const [displayQuestions, setDisplayQuestions] = useState([]); + + // 随机获取4个问题的函数 + const getRandomQuestions = () => { + const allQuestions = [...Questions.CUSTOM]; + const result: string[] = []; + const questionCount = Math.min(4, allQuestions.length); + + for (let i = 0; i < questionCount; i++) { + const randomIndex = Math.floor(Math.random() * allQuestions.length); + result.push(allQuestions.splice(randomIndex, 1)[0]); + } + + return result; + }; + + + + // 组件初始化时获取随机问题 + useEffect(() => { + setDisplayQuestions(getRandomQuestions()); + }, []); + + const handleClick = () => { + setIsRotating(true); + + // 更新随机问题 + setDisplayQuestions(getRandomQuestions()); + + // 动画结束后重置状态 + setTimeout(() => { + setIsRotating(false); + }, 1000); + }; + + const dispatch = useDispatch(); + const handleQuestion = async(question: string) => { + await toRoom(); + + dispatch( + setInitMsg(question) + ); + + }; + + return ( +
+
+ hello +
Hey,我是您的六纬AI小助手
+
+
+
+ whatsThing +
+ circle +
换一批
+
+
+ {displayQuestions.map((item, index) => ( +
handleQuestion(item)}> +
{item}
+ +
+ ))} +
+
+ ); +} diff --git a/src/pages/MainPage/MainArea/Antechamber/InvokeButton/index.module.less b/src/pages/MainPage/MainArea/Antechamber/InvokeButton/index.module.less index 66f2e3d..dee4bf7 100644 --- a/src/pages/MainPage/MainArea/Antechamber/InvokeButton/index.module.less +++ b/src/pages/MainPage/MainArea/Antechamber/InvokeButton/index.module.less @@ -1,68 +1,46 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - .wrapper { - position: relative; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - - - .btn { - width: max-content; - height: max-content; - border-radius: 50%; - display: flex; - justify-content: center; - align-items: center; - - .icon { - position: absolute; - } - } - - .text { - margin-top: 8px; - color: rgba(115, 122, 135, 1); - } + width: 88px; + height: 88px; + background: linear-gradient(180deg, #64c7ff 0%, #0165ff 100%); + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + border-radius: 50%; + position: relative; } -.cursor { - cursor: pointer; +.wrapper::before{ + position: absolute; + content: ""; + left: 0; + bottom: 0; + width: 26px; + height: 26px; + background: radial-gradient(farthest-corner at 100% 0%, #7BDCF0, #fff); + filter: blur(14px); } -.cursor:hover { - opacity: 0.8; +.wrapper::after{ + position: absolute; + content: ""; + left: 20%; + top: 0; + width: 26px; + height: 26px; + background: radial-gradient(farthest-corner at 100% 0%, #7BDCF0, #a4dbe6); + filter: blur(14px); } -.cursor:active { - opacity: 1; +.text { + color: #fff; + font-weight: 500; + font-size: 13px; } -.loader { - display: flex; - gap: 5px; +.call{ + width: 32px; + height: 32px; + object-fit: contain; + margin-bottom: 4px; } - -.dot { - width: 10px; - height: 10px; - border-radius: 50%; - background-color: white; - animation: glow 0.9s infinite; -} - -@keyframes glow { - 0% { - opacity: 1; - } - 40% { - opacity: 0.7; - } - 100% { - opacity: 0.3; - } -} \ No newline at end of file diff --git a/src/pages/MainPage/MainArea/Antechamber/InvokeButton/index.tsx b/src/pages/MainPage/MainArea/Antechamber/InvokeButton/index.tsx index aa52e97..59fde94 100644 --- a/src/pages/MainPage/MainArea/Antechamber/InvokeButton/index.tsx +++ b/src/pages/MainPage/MainArea/Antechamber/InvokeButton/index.tsx @@ -3,29 +3,23 @@ * SPDX-license-identifier: BSD-3-Clause */ -import Loading from './loading'; + import style from './index.module.less'; -import CallButtonSVG from '@/assets/img/CallWrapper.svg'; -import PhoneSVG from '@/assets/img/Phone.svg'; +import CallPng from "@/assets/img/call.png" + interface IInvokeButtonProps extends React.HTMLAttributes { loading?: boolean; + disable?: boolean; } function InvokeButton(props: IInvokeButtonProps) { - const { loading, className, ...rest } = props; + const {disable, loading, className, ...rest } = props; return ( -
-
- call - {loading ? ( - - ) : ( - phone - )} -
-
{loading ? '连接中' : '通话'}
+
+ call +
{disable ? '暂不可用':loading?'连接中':'发起通话'}
); } diff --git a/src/pages/MainPage/MainArea/Antechamber/index.module.less b/src/pages/MainPage/MainArea/Antechamber/index.module.less index a8f96b8..999dcf1 100644 --- a/src/pages/MainPage/MainArea/Antechamber/index.module.less +++ b/src/pages/MainPage/MainArea/Antechamber/index.module.less @@ -13,6 +13,7 @@ align-items: center; justify-content: center; + .avatar { /** * height = 128px in AvatarCard.avatar diff --git a/src/pages/MainPage/MainArea/Antechamber/index.tsx b/src/pages/MainPage/MainArea/Antechamber/index.tsx index e41cd41..50309fe 100644 --- a/src/pages/MainPage/MainArea/Antechamber/index.tsx +++ b/src/pages/MainPage/MainArea/Antechamber/index.tsx @@ -2,22 +2,46 @@ * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. * SPDX-license-identifier: BSD-3-Clause */ +import { useEffect, useState } from 'react'; +import { useDispatch } from 'react-redux'; +import { useSearchParams } from 'react-router-dom'; -import AvatarCard from '@/components/AvatarCard'; -import Utils from '@/utils/utils'; -import aigcConfig from '@/config'; import InvokeButton from '@/pages/MainPage/MainArea/Antechamber/InvokeButton'; +import HeaderGroup from '@/pages/MainPage/MainArea/Antechamber/HeaderGroup'; import { useJoin } from '@/lib/useCommon'; import style from './index.module.less'; +import { updateAIConfig } from '@/store/slices/room'; +import { requestPostMethod } from '@/app/base'; + function Antechamber() { + const dispatch = useDispatch() const [joining, dispatchJoin] = useJoin(); - const username = aigcConfig.BaseConfig.UserId; - const roomId = aigcConfig.BaseConfig.RoomId; + const [isDisable,setDisable] = useState(true) + const [searchParams] = useSearchParams(); + const userId = searchParams.get('userId') || '0' + const username = userId; + const roomId = userId; - const handleJoinRoom = () => { - if (!joining) { - dispatchJoin( + + const getToken = async () => { + const queryData = await requestPostMethod(`/api/token`)({roomId,userId:username}) + const res = await queryData?.json(); + if(res.code === 200){ + dispatch(updateAIConfig({user_token:res.data.token})) + setDisable(false) + } + + } + + useEffect(() => { + getToken() + },[]) + + + const handleJoinRoom = async() => { + if (!isDisable &&!joining) { + await dispatchJoin( { username, roomId, @@ -30,10 +54,8 @@ function Antechamber() { return (
- -
AI 语音助手
-
Powered by 豆包大模型和火山引擎视频云 RTC
- + +
); } diff --git a/src/pages/MainPage/MainArea/Room/AudioController.tsx b/src/pages/MainPage/MainArea/Room/AudioController.tsx index e3f153a..6d09bf9 100644 --- a/src/pages/MainPage/MainArea/Room/AudioController.tsx +++ b/src/pages/MainPage/MainArea/Room/AudioController.tsx @@ -3,15 +3,17 @@ * SPDX-license-identifier: BSD-3-Clause */ +import React from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import AudioLoading from '@/components/Loading/AudioLoading'; import { RootState } from '@/store'; import RtcClient from '@/lib/RtcClient'; import { setInterruptMsg } from '@/store/slices/room'; -import { useDeviceState } from '@/lib/useCommon'; +import { useDeviceState, useLeave } from '@/lib/useCommon'; import { COMMAND } from '@/utils/handler'; import style from './index.module.less'; -import StopRobotBtn from '@/assets/img/StopRobotBtn.svg'; +import LockMicroIcon from '@/assets/img/lockmicrophone.png'; +import MicroIcon from '@/assets/img/microphone.png'; +import HandleOffIcon from "@/assets/img/handoff.png" const THRESHOLD_VOLUME = 18; @@ -20,30 +22,39 @@ function AudioController(props: React.HTMLAttributes) { const dispatch = useDispatch(); const room = useSelector((state: RootState) => state.room); const volume = room.localUser.audioPropertiesInfo?.linearVolume || 0; - const { isAudioPublished } = useDeviceState(); + const { isAudioPublished,switchMic } = useDeviceState(); const isAITalking = room.isAITalking; const isLoading = volume >= THRESHOLD_VOLUME && isAudioPublished; + const leaveRoom = useLeave(); const handleInterrupt = () => { RtcClient.commandAudioBot(COMMAND.INTERRUPT); dispatch(setInterruptMsg()); }; + return (
- {isAudioPublished ? ( - isAITalking ? ( -
- StopRobotBtn - 点击打断 -
- ) : ( -
正在听...
- ) - ) : ( -
你已关闭麦克风
- )} - +
+ handoff +
挂断
+
+
switchMic(true)}> + lock +
{isAudioPublished ? '关麦' : '开麦'}
+
+ +
+
+ + + + + +
+
{isAITalking ? '点击打断' : '正在听'}
+
); } + export default AudioController; diff --git a/src/pages/MainPage/MainArea/Room/CameraArea.tsx b/src/pages/MainPage/MainArea/Room/CameraArea.tsx deleted file mode 100644 index f855dc8..0000000 --- a/src/pages/MainPage/MainArea/Room/CameraArea.tsx +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -import { useDispatch, useSelector } from 'react-redux'; -import { useEffect } from 'react'; -import { MediaType } from '@volcengine/rtc'; -import { RootState } from '@/store'; -import { useVisionMode } from '@/lib/useCommon'; -import styles from './index.module.less'; -import CameraCloseNoteSVG from '@/assets/img/CameraCloseNote.svg'; -import RtcClient from '@/lib/RtcClient'; -import { updateLocalUser } from '@/store/slices/room'; - -const LocalVideoID = 'local-video-player'; - -function CameraArea(props: React.HTMLAttributes) { - const { className, ...rest } = props; - const dispatch = useDispatch(); - const room = useSelector((state: RootState) => state.room); - const isVisionMode = useVisionMode(); - const localUser = room.localUser; - const isVideoPublished = localUser.publishVideo; - - const handleOperateCamera = () => { - !localUser.publishVideo ? RtcClient.startVideoCapture() : RtcClient.stopVideoCapture(); - - !localUser.publishVideo - ? RtcClient.publishStream(MediaType.VIDEO) - : RtcClient.unpublishStream(MediaType.VIDEO); - - dispatch( - updateLocalUser({ - publishVideo: !localUser.publishVideo, - }) - ); - }; - - useEffect(() => { - if (isVisionMode && isVideoPublished) { - RtcClient.setLocalVideoPlayer(room.localUser.username!, LocalVideoID); - } else { - RtcClient.setLocalVideoPlayer(room.localUser.username!); - } - }, [isVisionMode, isVideoPublished]); - - return isVisionMode ? ( -
- {isVideoPublished ? ( -
- ) : ( -
- close -
- 请 - - 打开摄像头 - -
-
体验豆包视觉理解模型
-
- )} -
- ) : null; -} - -export default CameraArea; diff --git a/src/pages/MainPage/MainArea/Room/Conversation.tsx b/src/pages/MainPage/MainArea/Room/Conversation.tsx index c4f50f3..0cbb013 100644 --- a/src/pages/MainPage/MainArea/Room/Conversation.tsx +++ b/src/pages/MainPage/MainArea/Room/Conversation.tsx @@ -3,13 +3,16 @@ * SPDX-license-identifier: BSD-3-Clause */ -import React, { useRef, useEffect } from 'react'; -import { useSelector } from 'react-redux'; +import React, { useRef, useEffect, useState } from 'react'; +import { useSelector,useDispatch } from 'react-redux'; import { Tag, Spin } from '@arco-design/web-react'; import { RootState } from '@/store'; import Loading from '@/components/Loading/HorizonLoading'; import Config from '@/config'; import styles from './index.module.less'; +import { COMMAND, INTERRUPT_PRIORITY } from '@/utils/handler'; +import RtcClient from '@/lib/RtcClient'; +import { setCurrentMsg, setHistoryMsg } from '@/store/slices/room'; const lines: (string | React.ReactNode)[] = []; @@ -17,17 +20,58 @@ function Conversation(props: React.HTMLAttributes) { const { className, ...rest } = props; const msgHistory = useSelector((state: RootState) => state.room.msgHistory); const { userId } = useSelector((state: RootState) => state.room.localUser); - const { isAITalking, isUserTalking } = useSelector((state: RootState) => state.room); + const { isAITalking, isUserTalking, initMsg} = useSelector((state: RootState) => state.room); const isAIReady = msgHistory.length > 0; const containerRef = useRef(null); + const [isFirst,setIsFirst] = useState(true); + const [isAudioBotEnabled, setIsAudioBotEnabled] = useState(false); + + const dispatch = useDispatch() useEffect(() => { + const checkAudioBotStatus = () => { + setIsAudioBotEnabled(RtcClient.getAudioBotEnabled()); + }; + + // 初始检查 + checkAudioBotStatus(); + + // 设置定时器定期检查 + const timer = setInterval(checkAudioBotStatus, 1000); + + // 清理函数 + return () => clearInterval(timer); + }, []); + + useEffect(() => { const container = containerRef.current; if (container) { container.scrollTop = container.scrollHeight - container.clientHeight; } }, [msgHistory.length]); + useEffect(() => { + if(isFirst && initMsg && isAudioBotEnabled){ + RtcClient.commandAudioBot(COMMAND.EXTERNAL_TEXT_TO_LLM, INTERRUPT_PRIORITY.HIGH, initMsg); + dispatch( + setHistoryMsg({ + text: initMsg, + user: RtcClient.basicInfo.user_id, + paragraph: true, + definite: true, + }) + ); + dispatch( + setCurrentMsg({ + text: initMsg, + user: RtcClient.basicInfo.user_id, + paragraph: true, + definite: true, + })) + setIsFirst(false) + } + },[isAudioBotEnabled]) + return (
{lines.map((line) => line)} @@ -54,7 +98,7 @@ function Conversation(props: React.HTMLAttributes) { {value}
{isAIReady && (isUserTalking || isAITalking) && index === msgHistory.length - 1 ? ( - + ) : ( '' )} diff --git a/src/pages/MainPage/MainArea/Room/ToolBar.tsx b/src/pages/MainPage/MainArea/Room/ToolBar.tsx deleted file mode 100644 index 3e0f66f..0000000 --- a/src/pages/MainPage/MainArea/Room/ToolBar.tsx +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -import { useSelector } from 'react-redux'; -import { useState } from 'react'; -import { Drawer } from '@arco-design/web-react'; -import { useDeviceState, useLeave } from '@/lib/useCommon'; -import { RootState } from '@/store'; -import { AI_MODEL } from '@/config'; -import utils from '@/utils/utils'; -import Menu from '../../Menu'; - -import style from './index.module.less'; -import CameraOpenSVG from '@/assets/img/CameraOpen.svg'; -import CameraCloseSVG from '@/assets/img/CameraClose.svg'; -import MicOpenSVG from '@/assets/img/MicOpen.svg'; -import SettingSVG from '@/assets/img/Setting.svg'; -import MicCloseSVG from '@/assets/img/MicClose.svg'; -import LeaveRoomSVG from '@/assets/img/LeaveRoom.svg'; - -function ToolBar(props: React.HTMLAttributes) { - const { className, ...rest } = props; - const room = useSelector((state: RootState) => state.room); - const [open, setOpen] = useState(false); - const model = room.aiConfig.Config.LLMConfig?.ModelName; - const leaveRoom = useLeave(); - const { isAudioPublished, isVideoPublished, switchMic, switchCamera } = useDeviceState(); - const handleSetting = () => { - setOpen(true); - }; - return ( -
- {utils.isMobile() ? ( - setting - ) : null} - switchMic(true)} - className={style.btn} - alt="mic" - /> - {model === AI_MODEL.VISION ? ( - switchCamera(true)} - className={style.btn} - alt="camera" - /> - ) : ( - '' - )} - leave - {utils.isMobile() ? ( - setOpen(false)} - style={{ - width: 'max-content', - }} - > - - - ) : null} -
- ); -} -export default ToolBar; diff --git a/src/pages/MainPage/MainArea/Room/index.module.less b/src/pages/MainPage/MainArea/Room/index.module.less index e5978ed..b7ce503 100644 --- a/src/pages/MainPage/MainArea/Room/index.module.less +++ b/src/pages/MainPage/MainArea/Room/index.module.less @@ -4,280 +4,221 @@ */ .wrapper { - position: relative; + position: relative; + width: 100%; + height: 100%; + box-sizing: border-box; + display: flex; + flex-direction: column; + padding-top: 38px; + background-color: #F4F6FA; + + .conversation { width: 100%; - height: 100%; - border-radius: 16px; - padding: 36px 72px; - box-sizing: border-box; + position: relative; + height: 0; + display: flex; + flex-direction: column; + flex:1 1 0; + overflow: auto; - .conversation { - width: 100%; - position: relative; - height: 100%; - /** - * 100% 为容器高度 - * 128px 为上层 DouBao Card Height - * 24px 为 margin top - * 36px * 2 为容器 padding - * 128 + 24 + 36 * 2 = 224px - */ - max-height: calc(100% - 224px - 8px); - display: flex; - flex-direction: column; - padding-bottom: 12px; - // background-color: black; - overflow-x: hidden; - overflow-y: auto; - margin-top: 24px; - .sentence { - position: relative; - display: flex; - flex-direction: row; - justify-content: flex-start; - align-items: center; - width: max-content; - white-space: normal; - max-width: 100%; - line-height: 28px; + .sentence { + position: relative; + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + width: max-content; + white-space: normal; + max-width: 100%; + line-height: 28px; + box-sizing: border-box; + - .content { - width: max-content; - } - } - - .user { - width: max-content; - border: 0px solid; - align-self: flex-end; - padding: 8px 12px 8px 12px; - border-radius: 12px 0px 12px 12px; - background: var(--background-color-bg-5, rgba(241, 243, 245, 1)); - margin-top: 12px; - margin-bottom: 12px; - } - .robot { - font-family: PingFang SC; - font-size: 14px; - font-weight: 400; - letter-spacing: 0.003em; - - border: 0px solid; - align-self: flex-start; - padding: 3px 12px 3px 0px; - } - - .loading-wrapper { - width: max-content; - display: inline-block; - - .loading { - margin-left: 8px; - width: max-content; - } - - .dot { - background-color: rgba(193, 163, 237, 1); - width: 8px; - height: 8px; - } - } - - .aiReadying { - font-family: PingFang SC; - font-size: 16px; - font-weight: 500; - color: rgba(27, 30, 61, 0.6); - text-align: center; - display: flex; - flex-direction: row; - justify-content: flex-start; - align-items: center; - line-height: 28px; - } - - .aiReading-spin { - margin-right: 12px; - line-height: 16px; - } - - .interruptTag { - width: max-content; - height: 22px; - padding: 0px 6px 0px 6px; - border-radius: 4px; - margin-left: 6px; - font-family: PingFang SC; - font-size: 12px; - font-weight: 400; - line-height: 22px; - letter-spacing: 0.003em; - color: var(--text-color-text-3, rgba(115, 122, 135, 1)); - background: var(--security-unknown-tag-unknown-1, rgba(241, 243, 245, 1)); - } + .content { + width: max-content; + background: #ffffff; + border-radius: 12px; + padding: 10px 12px; + } } - .conversation::-webkit-scrollbar { - width: 0px; - height: 0px; + .user { + width: max-content; + border: 0px solid; + align-self: flex-end; + margin-top: 12px; + margin-bottom: 12px; + margin-right: 15px; + + .content{ + border-radius: 30px 30px 0 30px; + background-color: #1580FF; + color:#fff; + } } - - .conversation::-webkit-scrollbar-thumb { - background: rgba(0,0,0,0); - border-radius: 0px; - } - - .conversation::-webkit-scrollbar-track { - background: rgba(0,0,0,0); - border-radius: 0px; + .robot { + font-family: PingFang SC; + font-size: 14px; + font-weight: 400; + letter-spacing: 0.003em; + + border: 0px solid; + align-self: flex-start; + padding: 3px 12px; } - .toolBar { - position: absolute; - right: 0px; - margin-right: 36px; - bottom: 36px; + .loading-wrapper { + width: max-content; + display: inline-block; + + .loading { + margin-left: 8px; + width: max-content; + } + + .dot { + background-color: rgba(193, 163, 237, 1); + width: 8px; + height: 8px; + } } - .controller { - position: absolute; - left: 0px; - bottom: 36px; - margin-left: 50%; - transform: translateX(-50%); + .aiReadying { + font-family: PingFang SC; + font-size: 16px; + font-weight: 500; + color: rgba(27, 30, 61, 0.6); + text-align: center; + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + line-height: 28px; + margin-left: 20px; } - .declare { - position: absolute; - bottom: 8px; - left: 12px; - color: var(--text-color-text-4, rgba(199, 204, 214, 1)); - font-size: 10px; - font-weight: 400; - line-height: 20px; + .aiReading-spin { + margin-right: 12px; } + + .interruptTag { + width: max-content; + height: 22px; + padding: 0px 6px 0px 6px; + border-radius: 4px; + margin-left: 6px; + font-family: PingFang SC; + font-size: 12px; + font-weight: 400; + line-height: 22px; + letter-spacing: 0.003em; + color: var(--text-color-text-3, rgba(115, 122, 135, 1)); + background: var(--security-unknown-tag-unknown-1, rgba(241, 243, 245, 1)); + } + } + + .conversation::-webkit-scrollbar { + width: 0px; + height: 0px; + } + + .conversation::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0); + border-radius: 0px; + } + + .conversation::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0); + border-radius: 0px; + } + + .controller { + display: flex; + align-items: center; + justify-content: center; + gap: 16px; + background-color: #fff; + padding: 8px 35px; + + .talkWrapper { + --h: 16px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + padding: 8px 16px; + background-color: #e3efff; + border-radius: 20px; + user-select: none; + gap: 8px; + min-width: 124px; + color: #0078ff; + } + + .listenerDot { + display: flex; + align-items: center; + justify-content: center; + position: relative; + height: var(--h); + width: 36px; + + span { + display: inline-block; + width: 4px; + margin: 0 1px; + background-color: #4898fc; + border-radius: 2px; + height: calc(var(--h) - var(--d) * 4px); + transition: height 0.2s ease; + opacity: calc(1 - var(--d) * 0.4); + } + } + + .isTalking { + span { + animation: soundWave 1s infinite ease-in-out; + } + + span:nth-child(1) { + animation-delay: 0s; + } + span:nth-child(2) { + animation-delay: 0.2s; + } + span:nth-child(3) { + animation-delay: 0.4s; + } + span:nth-child(4) { + animation-delay: 0.6s; + } + span:nth-child(5) { + animation-delay: 0.8s; + } + } + + @keyframes soundWave { + 0%, + 100% { + height: 4px; + } + 50% { + height: 16px; + } + } + + .microphoneWrapper { + display: flex; + align-items: center; + background-color: #f6f6f6; + padding: 10px 15px; + border-radius: 400px; + } + } } .mobile { - padding: 12px 28px; + padding-top: 12px; } - -.text { - width: 100%; - text-align: center; - color: rgba(148, 116, 255, 1); - font-size: 14px; - font-weight: 500; - line-height: 22px; -} - -.btns { - width: 100%; - display: flex; - flex-direction: row; - justify-content: flex-end; - align-items: center; - gap: 16px; - - .setting { - background-color: rgba(111, 111, 111, 0.497); - border-radius: 50%; - width: 48px; - height: 48px; - padding: 12px; - box-sizing: border-box; - cursor: pointer; - } - - .btn { - cursor: pointer; - } - - .btn:hover { - opacity: 0.8; - } - - .btn:active { - opacity: 1; - } -} - -.column { - flex-direction: column !important; - align-items: flex-end !important; -} - -.interrupt { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - background: #FFFFFF; - border-radius: 4px; - box-shadow: 0px 2px 1px 0px rgba(0, 0, 0, 0.08), 0px 0px 0px 1px rgba(221, 226, 233, 1); - border-color: #d9d9d9; - width: 81px; - height: 24px; - gap: 4px; - cursor: pointer; - user-select: none; - -webkit-user-select: none; /* Safari */ - -moz-user-select: none; /* Firefox */ - -ms-user-select: none; /* Internet Explorer/Edge */ - - .interrupt-text { - color: var(--text-color-text-3, rgba(115, 122, 135, 1)); - font-size: 12px; - } - - &:hover { - opacity: 0.8; - } - - &:active { - opacity: 1; - } -} - -.camera-wrapper { - position: absolute; - top: 16px; - right: 16px; - width: 320px; - height: 200px; - border-radius: 8px; - background: var(--line-color-border-2, rgba(234, 237, 241, 1)); - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - border: 0.81px solid var(--line-color-border-3, rgba(221, 226, 233, 1)); - overflow: hidden; - z-index: 4; - - .camera-player { - width: 100%; - height: 100%; - border-radius: 8px; - } - - .camera-placeholder { - width: 100%; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - font-size: 12px; - color: var(--text-color-text-3, rgba(115, 122, 135, 1)); - - .camera-placeholder-close-note { - margin-bottom: 8px; - } - - .camera-open-btn { - color: var(--primary-color-primary-6, rgba(22, 100, 255, 1)); - cursor: pointer; - } - } -} \ No newline at end of file diff --git a/src/pages/MainPage/MainArea/Room/index.tsx b/src/pages/MainPage/MainArea/Room/index.tsx index 56c3656..185b623 100644 --- a/src/pages/MainPage/MainArea/Room/index.tsx +++ b/src/pages/MainPage/MainArea/Room/index.tsx @@ -3,24 +3,18 @@ * SPDX-license-identifier: BSD-3-Clause */ -import AvatarCard from '@/components/AvatarCard'; + import Conversation from './Conversation'; -import ToolBar from './ToolBar'; -import CameraArea from './CameraArea'; + import AudioController from './AudioController'; import utils from '@/utils/utils'; import style from './index.module.less'; -import DoubaoAvatar from '@/assets/img/DoubaoAvatar.png'; function Room() { return (
- - {utils.isMobile() ? null : } - -
AI生成内容由大模型生成,不能完全保障真实
); } diff --git a/src/pages/MainPage/MainArea/index.module.less b/src/pages/MainPage/MainArea/index.module.less index ed60a57..bc0f759 100644 --- a/src/pages/MainPage/MainArea/index.module.less +++ b/src/pages/MainPage/MainArea/index.module.less @@ -94,7 +94,6 @@ font-family: PingFang SC; font-size: 16px; font-weight: 500; - line-height: 18px; letter-spacing: 0.003em; color: rgba(27, 30, 61, 0.6); margin-top: 12px; diff --git a/src/pages/MainPage/Menu/components/DeviceDrawerButton/index.module.less b/src/pages/MainPage/Menu/components/DeviceDrawerButton/index.module.less deleted file mode 100644 index 5bddcf7..0000000 --- a/src/pages/MainPage/Menu/components/DeviceDrawerButton/index.module.less +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -.wrapper { - width: 100%; - display: flex; - flex-direction: row; - gap: 24px; - padding: 8px 16px; - - - .label { - display: flex; - flex-direction: column; - align-items: flex-start; - line-height: 16px; - gap: 12px; - - .label-text { - font-family: PingFang SC; - font-size: 14px; - font-weight: 500; - line-height: 22px; - letter-spacing: 0.003em; - text-align: left; - } - } - - .value { - display: flex; - flex-direction: column; - justify-content: center; - align-items: flex-start; - gap: 18px; - } -} \ No newline at end of file diff --git a/src/pages/MainPage/Menu/components/DeviceDrawerButton/index.tsx b/src/pages/MainPage/Menu/components/DeviceDrawerButton/index.tsx deleted file mode 100644 index 56024fe..0000000 --- a/src/pages/MainPage/Menu/components/DeviceDrawerButton/index.tsx +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -import { useMemo } from 'react'; -import { useSelector, useDispatch } from 'react-redux'; -import { MediaType } from '@volcengine/rtc'; -import { Switch, Select } from '@arco-design/web-react'; -import DrawerRowItem from '@/components/DrawerRowItem'; -import { RootState } from '@/store'; -import RtcClient from '@/lib/RtcClient'; -import { useDeviceState } from '@/lib/useCommon'; -import { updateSelectedDevice } from '@/store/slices/device'; -import utils from '@/utils/utils'; -import styles from './index.module.less'; - -interface IDeviceDrawerButtonProps { - type?: MediaType.AUDIO | MediaType.VIDEO; -} - -const DEVICE_NAME = { - [MediaType.AUDIO]: '麦克风', - [MediaType.VIDEO]: '摄像头', -}; - -function DeviceDrawerButton(props: IDeviceDrawerButtonProps) { - const { type = MediaType.AUDIO } = props; - const device = useDeviceState(); - const isEnable = type === MediaType.AUDIO ? device.isAudioPublished : device.isVideoPublished; - const switcher = type === MediaType.AUDIO ? device.switchMic : device.switchCamera; - const devicePermissions = useSelector((state: RootState) => state.device.devicePermissions); - const devices = useSelector((state: RootState) => state.device); - const selectedDevice = - type === MediaType.AUDIO ? devices.selectedMicrophone : devices.selectedCamera; - const permission = devicePermissions?.[type === MediaType.AUDIO ? 'audio' : 'video']; - - const dispatch = useDispatch(); - const deviceList = useMemo( - () => (type === MediaType.AUDIO ? devices.audioInputs : devices.videoInputs), - [devices] - ); - - const handleDeviceChange = (value: string) => { - RtcClient.switchDevice(type, value); - if (type === MediaType.AUDIO) { - dispatch( - updateSelectedDevice({ - selectedMicrophone: value, - }) - ); - } - if (type === MediaType.VIDEO) { - dispatch( - updateSelectedDevice({ - selectedCamera: value, - }) - ); - } - }; - - return ( - -
{DEVICE_NAME[type]}
-
- switcher(enable)} - disabled={!permission} - /> - -
-
- ), - }} - /> - ); -} - -export default DeviceDrawerButton; diff --git a/src/pages/MainPage/Menu/components/Interrupt/index.module.less b/src/pages/MainPage/Menu/components/Interrupt/index.module.less deleted file mode 100644 index 5c1219c..0000000 --- a/src/pages/MainPage/Menu/components/Interrupt/index.module.less +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -.interrupt { - position: relative; - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - - .label { - font-size: 13px; - font-weight: 400; - line-height: 22px; - color: var(--text-color-text-1, rgba(12, 13, 14, 1)); - - .icon { - margin-left: 4px; - } - } -} diff --git a/src/pages/MainPage/Menu/components/Interrupt/index.tsx b/src/pages/MainPage/Menu/components/Interrupt/index.tsx deleted file mode 100644 index 4ea7142..0000000 --- a/src/pages/MainPage/Menu/components/Interrupt/index.tsx +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -import { Popover, Switch } from '@arco-design/web-react'; -import { IconQuestionCircle } from '@arco-design/web-react/icon'; -import { useState } from 'react'; -import { useDispatch } from 'react-redux'; -import Config from '@/config'; -import styles from './index.module.less'; -import RtcClient from '@/lib/RtcClient'; -import { clearHistoryMsg } from '@/store/slices/room'; - -function Interrupt() { - const dispatch = useDispatch(); - const [switchAble, setSwitchAble] = useState(true); - const [enable, setEnable] = useState(Config.InterruptMode); - const handleChange = () => { - setSwitchAble(false); - setEnable(!enable); - Config.InterruptMode = !enable; - if (RtcClient.getAudioBotEnabled()) { - dispatch(clearHistoryMsg()); - } - RtcClient.updateAudioBot(); - setTimeout(() => { - setSwitchAble(true); - }, 3000); - }; - return ( -
-
- 语音打断 - - - -
-
- -
-
- ); -} - -export default Interrupt; diff --git a/src/pages/MainPage/Menu/components/Operation/index.module.less b/src/pages/MainPage/Menu/components/Operation/index.module.less deleted file mode 100644 index 1c46bed..0000000 --- a/src/pages/MainPage/Menu/components/Operation/index.module.less +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -.device { - display: flex; - flex-direction: column; - gap: 16px; -} - -.box { - position: relative; - width: 100%; - border-radius: 16px; - background-color: white; - border: 1px solid var(--line-color-border-2, rgba(234, 237, 241, 1)); - padding: 16px 24px 16px 24px; - box-sizing: border-box; - margin-bottom: 16px; -} \ No newline at end of file diff --git a/src/pages/MainPage/Menu/components/Operation/index.tsx b/src/pages/MainPage/Menu/components/Operation/index.tsx deleted file mode 100644 index 860944e..0000000 --- a/src/pages/MainPage/Menu/components/Operation/index.tsx +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -import { MediaType } from '@volcengine/rtc'; -import DeviceDrawerButton from '../DeviceDrawerButton'; -import { useVisionMode } from '@/lib/useCommon'; -import Interrupt from '../Interrupt'; -import styles from './index.module.less'; - -function Operation() { - const isVisionMode = useVisionMode(); - return ( -
- - - {isVisionMode ? : ''} -
- ); -} - -export default Operation; diff --git a/src/pages/MainPage/Menu/index.module.less b/src/pages/MainPage/Menu/index.module.less deleted file mode 100644 index e33628f..0000000 --- a/src/pages/MainPage/Menu/index.module.less +++ /dev/null @@ -1,184 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -.wrapper { - width: 200px; - height: 100%; - border-radius: 16px; - display: flex; - flex-direction: column; - align-items: center; - - .info { - .bold { - font-size: 13px; - font-weight: 500; - line-height: 22px; - color: var(--text-color-text-1, rgba(12, 13, 14, 1)); - } - - .gray { - display: flex; - flex-direction: row; - align-items: center; - font-size: 13px; - font-weight: 400; - line-height: 22px; - color: var(--text-color-text-3, rgba(115, 122, 135, 1)); - - .value { - width: 65%; - font-size: 12px; - font-weight: 500; - margin-left: 5px; - } - - :global { - .arco-typography { - margin-bottom: 0px; - } - } - } - - .buttonArea { - width: 100%; - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - margin-top: 8px; - - .getMore { - width: 100%; - color: #fff; - height: 32px; - text-shadow: none; - box-shadow: none; - border: none; - padding: 0px 24px; - background: linear-gradient(56.59deg, #3C73FF 15.53%, #6E41EE 62.28%, #D641EE 90.32%), - radial-gradient(203.56% 121.74% at 27.12% -21.74%, rgba(82, 182, 255, 0.2) 0%, rgba(143, 65, 238, 0) 100%), - radial-gradient(134.75% 51.95% at 26.69% 5.8%, rgba(157, 214, 255, 0.1) 0%, rgba(143, 65, 238, 0) 100%), - radial-gradient(82.39% 83.92% at 147.46% 76.45%, rgba(82, 99, 255, 0.8) 0%, rgba(143, 65, 238, 0) 100%); - border-radius: 4px; - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - - color: var(--Primary-Neutral-0, #FFF); - text-align: center; - - /* Body/body-2 medium */ - font-family: "PingFang SC"; - font-size: 13px; - font-style: normal; - font-weight: 500; - cursor: pointer; - } - - .getMore:hover { - opacity: 0.9; - } - - .getMore:active { - opacity: 1; - } - - .getMore[disabled], - .getMore[disabled]:hover { - color: #fff; - background: linear-gradient(95.87deg, #1664FF 0%, #8040FF 97.7%); - opacity: 0.8; - } - } - } - - .questions { - display: flex; - flex-direction: column; - gap: 8px; - - .title { - font-size: 13px; - font-weight: 500; - line-height: 22px; - } - - .line { - font-size: 12px; - font-weight: 400; - line-height: 20px; - color: rgba(66, 70, 78, 1); - cursor: pointer; - } - } - - .device { - display: flex; - flex-direction: column; - gap: 16px; - } - - .box { - position: relative; - width: 100%; - border-radius: 16px; - background-color: white; - border: 1px solid var(--line-color-border-2, rgba(234, 237, 241, 1)); - padding: 16px 24px 16px 24px; - box-sizing: border-box; - margin-bottom: 16px; - } - - .resetTime { - position: relative; - width: 100%; - border-radius: 16px; - padding: 0px 24px 8px 24px; - box-sizing: border-box; - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - - user-select: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - - .normalLine { - color: #42464E; - /* Body/body-1 regular */ - font-family: "PingFang SC"; - font-size: 12px; - font-style: normal; - font-weight: 400; - line-height: 20px; /* 166.667% */ - letter-spacing: 0.036px; - opacity: 0.8; - } - } -} - -.mobile-camera-wrapper { - position: relative; - width: 100%; - height: 100%; - border-radius: 16px; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - margin-bottom: 16px; - - .mobile-camera { - position: relative !important; - width: 100% !important; - height: 100% !important; - top: auto !important; - right: auto !important; - } -} \ No newline at end of file diff --git a/src/pages/MainPage/Menu/index.tsx b/src/pages/MainPage/Menu/index.tsx deleted file mode 100644 index a60a6ad..0000000 --- a/src/pages/MainPage/Menu/index.tsx +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -import VERTC from '@volcengine/rtc'; -import { Tooltip, Typography } from '@arco-design/web-react'; -import { useDispatch, useSelector } from 'react-redux'; -import { useVisionMode } from '@/lib/useCommon'; -import { RootState } from '@/store'; -import RtcClient from '@/lib/RtcClient'; -import Operation from './components/Operation'; -import { Questions } from '@/config'; -import { COMMAND, INTERRUPT_PRIORITY } from '@/utils/handler'; -import CameraArea from '../MainArea/Room/CameraArea'; -import { setCurrentMsg, setHistoryMsg } from '@/store/slices/room'; -import utils from '@/utils/utils'; -import styles from './index.module.less'; - -function Menu() { - const dispatch = useDispatch(); - const room = useSelector((state: RootState) => state.room); - const scene = room.scene; - const isJoined = room?.isJoined; - const isVisionMode = useVisionMode(); - - const handleQuestion = (question: string) => { - RtcClient.commandAudioBot(COMMAND.EXTERNAL_TEXT_TO_LLM, INTERRUPT_PRIORITY.HIGH, question); - dispatch( - setHistoryMsg({ - text: question, - user: RtcClient.basicInfo.user_id, - paragraph: true, - definite: true, - }) - ); - dispatch( - setCurrentMsg({ - text: question, - user: RtcClient.basicInfo.user_id, - paragraph: true, - definite: true, - }) - ); - }; - - return ( -
- {isJoined && utils.isMobile() && isVisionMode ? ( -
- -
- ) : null} -
-
Demo Version 1.4.0
-
SDK Version {VERTC.getSdkVersion()}
- {isJoined ? ( -
- 房间ID{' '} - - - {room.roomId || '-'} - - -
- ) : ( - '' - )} -
- {isJoined ? ( -
-
点击下述问题进行提问:
- {Questions[scene].map((question) => ( -
handleQuestion(question)} className={styles.line} key={question}> - {question} -
- ))} -
- ) : ( - '' - )} - {isJoined ? : ''} -
- ); -} - -export default Menu; diff --git a/src/pages/MainPage/index.module.less b/src/pages/MainPage/index.module.less index 0653f31..227467d 100644 --- a/src/pages/MainPage/index.module.less +++ b/src/pages/MainPage/index.module.less @@ -17,7 +17,7 @@ width: calc(100% - 220px); height: 100%; margin-right: 2%; - background-color: white; + background: linear-gradient( 180deg, #fff 0%, #eee 100%); border-radius: 16px; overflow: hidden; } diff --git a/src/pages/MainPage/index.tsx b/src/pages/MainPage/index.tsx index b221f4c..23ecae3 100644 --- a/src/pages/MainPage/index.tsx +++ b/src/pages/MainPage/index.tsx @@ -3,9 +3,8 @@ * SPDX-license-identifier: BSD-3-Clause */ -import Header from '@/components/Header'; import ResizeWrapper from '@/components/ResizeWrapper'; -import Menu from './Menu'; + import utils from '@/utils/utils'; import MainArea from './MainArea'; import styles from './index.module.less'; @@ -13,7 +12,6 @@ import styles from './index.module.less'; export default function () { return ( -
- {utils.isMobile() ? null : ( -
- -
- )}
); diff --git a/src/store/slices/room.ts b/src/store/slices/room.ts index 0812fe7..cb9e7df 100644 --- a/src/store/slices/room.ts +++ b/src/store/slices/room.ts @@ -92,11 +92,12 @@ export interface RoomState { definite: boolean; }; }; + initMsg: string // 初始化信息 } const initialState: RoomState = { time: -1, - scene: SCENE.INTELLIGENT_ASSISTANT, + scene: SCENE.CUSTOM, remoteUsers: [], localUser: { publishAudio: true, @@ -113,12 +114,16 @@ const initialState: RoomState = { msgHistory: [], currentConversation: {}, + initMsg:'' }; export const roomSlice = createSlice({ name: 'room', initialState, reducers: { + setInitMsg:(state,{payload})=>{ + state.initMsg = payload + }, localJoinRoom: ( state, { @@ -278,6 +283,7 @@ export const { setInterruptMsg, updateNetworkQuality, updateScene, + setInitMsg } = roomSlice.actions; export default roomSlice.reducer; diff --git a/src/utils/handler.ts b/src/utils/handler.ts index ef7fc67..0cf8608 100644 --- a/src/utils/handler.ts +++ b/src/utils/handler.ts @@ -5,12 +5,7 @@ import { useDispatch } from 'react-redux'; import logger from './logger'; -import { - setCurrentMsg, - setHistoryMsg, - setInterruptMsg, - updateAITalkState, -} from '@/store/slices/room'; +import { setCurrentMsg, setHistoryMsg, setInterruptMsg, updateAITalkState } from '@/store/slices/room'; import RtcClient from '@/lib/RtcClient'; import Utils from '@/utils/utils'; @@ -141,8 +136,8 @@ export const useMessageHandler = () => { ToolCallID: parsed?.tool_calls?.[0]?.id, Content: map[name.toLocaleLowerCase().replaceAll('_', '')], }), - 'func', - ), + 'func' + ) ); }, }; diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 2166d39..a18ac53 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -6,9 +6,7 @@ import { Msg, RoomState } from '@/store/slices/room'; import RtcClient from '@/lib/RtcClient'; - class Utils { - formatTime = (time: number): string => { if (time < 0) { return '00:00'; @@ -75,10 +73,7 @@ class Utils { if (arr.length) { const last = arr.at(-1)!; const { user, value, isInterrupted } = last; - if ( - (added.user === RtcClient.basicInfo.user_id && last.user === added.user) || - (user === added.user && added.value.startsWith(value) && value.trim()) - ) { + if ((added.user === RtcClient.basicInfo.user_id && last.user === added.user) || (user === added.user && added.value.startsWith(value) && value.trim())) { arr.pop(); added.isInterrupted = isInterrupted; } @@ -119,7 +114,7 @@ class Utils { * @note TLV 数据格式 * | magic number | length(big-endian) | value | * @param {ArrayBufferLike} tlvBuffer - * @returns + * @returns */ tlv2String(tlvBuffer: ArrayBufferLike) { const typeBuffer = new Uint8Array(tlvBuffer, 0, 4); @@ -131,8 +126,7 @@ class Utils { type += String.fromCharCode(typeBuffer[i]); } - const length = - (lengthBuffer[0] << 24) | (lengthBuffer[1] << 16) | (lengthBuffer[2] << 8) | lengthBuffer[3]; + const length = (lengthBuffer[0] << 24) | (lengthBuffer[1] << 16) | (lengthBuffer[2] << 8) | lengthBuffer[3]; const value = new TextDecoder().decode(valueBuffer.subarray(0, length));