byt-lingxiao-ai 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Binary file
Binary file
@@ -3746,7 +3746,7 @@ if (typeof window !== 'undefined') {
3746
3746
  var es_iterator_constructor = __webpack_require__(8111);
3747
3747
  // EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.for-each.js
3748
3748
  var es_iterator_for_each = __webpack_require__(7588);
3749
- ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindow.vue?vue&type=template&id=43521054&scoped=true
3749
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindow.vue?vue&type=template&id=62955cf4&scoped=true
3750
3750
  var render = function render() {
3751
3751
  var _vm = this,
3752
3752
  _c = _vm._self._c;
@@ -3772,10 +3772,10 @@ var render = function render() {
3772
3772
  "click": _vm.toggleWindow
3773
3773
  }
3774
3774
  }, [_c('div', {
3775
- staticClass: "chat-ai-avater"
3775
+ class: ['chat-ai-avater', _vm.avaterStatus]
3776
3776
  }), _c('div', {
3777
3777
  staticClass: "chat-ai-text"
3778
- }, [_vm._v("凌霄AI")])]), _c('div', {
3778
+ }, [_vm._v(_vm._s(_vm.avaterText))])]), _c('div', {
3779
3779
  directives: [{
3780
3780
  name: "show",
3781
3781
  rawName: "v-show",
@@ -3842,8 +3842,16 @@ var render = function render() {
3842
3842
  }, [_vm._v(_vm._s(message.content))])]) : _c('div', {
3843
3843
  staticClass: "chat-window-message-ai"
3844
3844
  }, [_c('div', {
3845
- staticClass: "ai-message"
3846
- }, [_vm._v(_vm._s(message.content))])])]);
3845
+ staticClass: "ai-render"
3846
+ }, [_c('div', {
3847
+ staticClass: "ai-thinking"
3848
+ }, [_c('div', {
3849
+ staticClass: "ai-thinking-time"
3850
+ }, [_vm._v("思考用时" + _vm._s(message.time) + "秒")]), _c('div', {
3851
+ staticClass: "ai-thinking-content"
3852
+ }, [_vm._v(_vm._s(message.thinking))])]), _c('div', {
3853
+ staticClass: "ai-content"
3854
+ }, [_vm._v(_vm._s(message.content))])])])]);
3847
3855
  }), 0), _c('div', {
3848
3856
  staticClass: "chat-window-footer"
3849
3857
  }, [_c('div', {
@@ -3951,6 +3959,8 @@ var es_typed_array_with = __webpack_require__(9577);
3951
3959
 
3952
3960
 
3953
3961
 
3962
+
3963
+
3954
3964
  const SAMPLE_RATE = 16000;
3955
3965
  const FRAME_SIZE = 512;
3956
3966
  /* harmony default export */ var ChatWindowvue_type_script_lang_js = ({
@@ -3980,19 +3990,12 @@ const FRAME_SIZE = 512;
3980
3990
  type: 'ai',
3981
3991
  sender: 'AI',
3982
3992
  time: '',
3983
- content: '欢迎来到凌霄大模型AI对话。'
3984
- }, {
3985
- id: 3,
3986
- type: 'ai',
3987
- sender: 'AI',
3988
- time: '',
3989
- content: '请输入您的问题。'
3990
- }, {
3991
- id: 4,
3992
- type: 'user',
3993
- sender: '用户',
3994
- time: '',
3995
- content: '你好,欢迎来到凌霄大模型AI对话。'
3993
+ thinking: '嗯,用户问的是回转窑的工业应用。首先,我需要回忆一下之前对话的内容。用户之前让我解释了水泥的制作流程,特别是提到了回转窑在高温煅烧熟料中的作用。',
3994
+ charts: [{
3995
+ title: '',
3996
+ options: {}
3997
+ }],
3998
+ content: '回转窑(Rotary Kiln)是一种长筒形旋转煅烧设备(类似倾斜安装的大管子),因其独特的旋转运动和高温耐火衬里设计,在多个工业领域都有广泛应用'
3996
3999
  }],
3997
4000
  // 消息列表
3998
4001
  isRecording: false,
@@ -4016,9 +4019,29 @@ const FRAME_SIZE = 512;
4016
4019
  // 音频处理节点
4017
4020
  robotStatus: 'leaving',
4018
4021
  // 机器人状态 waiting, speaking, leaving, entering
4022
+ avaterStatus: 'normal',
4023
+ // 头像状态 normal output thinking
4024
+ buffer: '',
4025
+ // 音频缓冲区
4026
+ currentMessage: null,
4027
+ // 当前消息
4028
+ inTag: false,
4029
+ // 是否在标签页
4030
+ tagBuilder: '',
4031
+ // 标签构建器
4019
4032
  audioBuffer: new Float32Array(0) // 音频缓冲区
4020
4033
  };
4021
4034
  },
4035
+ computed: {
4036
+ avaterText() {
4037
+ const textMap = {
4038
+ 'normal': '凌霄AI',
4039
+ 'thinking': '思考中',
4040
+ 'output': '语音中'
4041
+ };
4042
+ return textMap[this.avaterStatus];
4043
+ }
4044
+ },
4022
4045
  mounted() {
4023
4046
  this.initWebSocket();
4024
4047
 
@@ -4131,8 +4154,10 @@ const FRAME_SIZE = 512;
4131
4154
  } else if (data.code === 0) {
4132
4155
  if (data.data.type === 'detection') {
4133
4156
  console.log('检测到唤醒词...');
4157
+ this.avaterStatus = 'normal';
4134
4158
  } else if (data.data.type === 'Collecting') {
4135
4159
  console.log('状态: 采集中...');
4160
+ this.avaterStatus = 'thinking';
4136
4161
  } else if (data.data.type === 'command') {
4137
4162
  // 根据指令改变机器人的状态
4138
4163
  console.log('状态: 处理中...');
@@ -4170,6 +4195,32 @@ const FRAME_SIZE = 512;
4170
4195
  this.ws.close();
4171
4196
  }
4172
4197
  },
4198
+ createAiMessage() {
4199
+ const message = {
4200
+ id: this.messages.length + 1,
4201
+ type: 'ai',
4202
+ sender: 'AI',
4203
+ time: '',
4204
+ thinking: '',
4205
+ charts: [],
4206
+ content: ''
4207
+ };
4208
+ this.messages.push(message);
4209
+ this.currentMessage = message;
4210
+ return message;
4211
+ },
4212
+ createUserMessage(content) {
4213
+ const message = {
4214
+ id: this.messages.length + 1,
4215
+ type: 'user',
4216
+ sender: '用户',
4217
+ time: '',
4218
+ content
4219
+ };
4220
+ this.messages.push(message);
4221
+ this.inputMessage = '';
4222
+ return message;
4223
+ },
4173
4224
  async initAudio() {
4174
4225
  if (this.isRecording) return;
4175
4226
  try {
@@ -4212,20 +4263,19 @@ const FRAME_SIZE = 512;
4212
4263
  return;
4213
4264
  }
4214
4265
  const message = this.inputMessage.trim();
4266
+ // 初始化信息
4267
+ this.initState();
4215
4268
  // 发送消息
4216
- this.messages.push({
4217
- id: this.messages.length + 1,
4218
- type: 'user',
4219
- sender: '用户',
4220
- time: new Date().toLocaleTimeString(),
4221
- content: this.inputMessage
4222
- });
4223
- this.inputMessage = '';
4269
+ this.createUserMessage(message);
4270
+ // 创建AI消息
4271
+ this.createAiMessage();
4224
4272
  try {
4225
- const token = `Bearer 24ab99b4-4b59-42a0-84df-1d73a96e70cd`;
4273
+ const controller = new AbortController();
4274
+ const token = `Bearer e298f087-85bc-48c2-afb9-7c69ffc911aa`;
4226
4275
  const response = await fetch('/bytserver/api-model/chat/stream', {
4227
4276
  timeout: 30000,
4228
4277
  method: 'POST',
4278
+ signal: controller.signal,
4229
4279
  headers: {
4230
4280
  'Content-Type': 'application/json',
4231
4281
  'Authorization': token
@@ -4237,13 +4287,26 @@ const FRAME_SIZE = 512;
4237
4287
  if (!response.ok) {
4238
4288
  throw new Error(`${response.status}`);
4239
4289
  }
4240
- console.log('响应状态:', response.status);
4241
- // 解析响应流
4242
- this.parseResponseStream(response.body);
4290
+ const render = response.body.getReader();
4291
+ const decoder = new TextDecoder();
4292
+
4293
+ // eslint-disable-next-line no-constant-condition
4294
+ while (true) {
4295
+ const {
4296
+ done,
4297
+ value
4298
+ } = await render.read();
4299
+ if (done) break;
4300
+ const chunk = decoder.decode(value, {
4301
+ stream: true
4302
+ });
4303
+ this.processStreamChunk(chunk);
4304
+ }
4243
4305
  } catch (error) {
4244
4306
  console.error('发送消息失败:', error);
4245
4307
  }
4246
4308
  },
4309
+ initState() {},
4247
4310
  // 分析音频命令
4248
4311
  analyzeAudioCommand(command) {
4249
4312
  console.log('分析音频命令:', command);
@@ -4271,9 +4334,90 @@ const FRAME_SIZE = 512;
4271
4334
  this.stop();
4272
4335
  }
4273
4336
  },
4274
- // 解析响应流
4275
- parseResponseStream(body) {
4276
- console.log(body);
4337
+ processStreamChunk(chunk) {
4338
+ console.log('原始数据:', chunk);
4339
+ try {
4340
+ this.buffer += chunk;
4341
+
4342
+ // eslint-disable-next-line no-constant-condition
4343
+ while (true) {
4344
+ const eventEnd = this.buffer.indexOf('\n\n');
4345
+ if (eventEnd === -1) break;
4346
+ const eventData = this.buffer.slice(0, eventEnd);
4347
+ this.buffer = this.buffer.slice(eventEnd + 2);
4348
+ console.log('解析数据:', eventData);
4349
+ this.processEventData(eventData);
4350
+ }
4351
+ } catch (error) {
4352
+ console.error('流数据处理异常:', error);
4353
+ this.streaming = false;
4354
+ this.response = this.$t('3d.chat.dataFormatError');
4355
+ this.$forceUpdate();
4356
+ }
4357
+ },
4358
+ processEventData(data) {
4359
+ data.split('\n').forEach(line => {
4360
+ console.log('原始数据:', line);
4361
+ if (!line.startsWith('data:')) return;
4362
+ const jsonStr = line.replace(/^data:\s*/, '').trim();
4363
+ if (jsonStr === '[DONE]') return;
4364
+ try {
4365
+ const data = this.safeJsonParse(jsonStr);
4366
+ this.processContentDelta(data.choices[0].delta);
4367
+ } catch (e) {
4368
+ console.warn('JSON解析跳过:', e.message);
4369
+ }
4370
+ });
4371
+ },
4372
+ safeJsonParse(jsonStr) {
4373
+ try {
4374
+ return JSON.parse(jsonStr);
4375
+ } catch (error) {
4376
+ console.warn('JSON parse failed:', jsonStr);
4377
+ return null;
4378
+ }
4379
+ },
4380
+ processContentDelta(delta) {
4381
+ const content = delta.content || '';
4382
+ if (!content || !this.currentMessage) return;
4383
+ for (let i = 0; i < content.length; i++) {
4384
+ const char = content[i];
4385
+
4386
+ // 处理正在拼接的标签
4387
+ if (this.inTag) {
4388
+ this.tagBuilder += char;
4389
+ if (char === '>') {
4390
+ const tag = this.tagBuilder;
4391
+ if (tag === '<think>') {
4392
+ this.avaterStatus = 'thinking';
4393
+ } else if (tag === '</think>') {
4394
+ this.avaterStatus = 'output';
4395
+ } else {
4396
+ console.log('无效标签:', tag);
4397
+ }
4398
+
4399
+ // 重置
4400
+ this.inTag = false;
4401
+ this.tagBuilder = '';
4402
+ }
4403
+ continue;
4404
+ }
4405
+
4406
+ // 检测是否是标签开始
4407
+ if (char === '<') {
4408
+ this.inTag = true;
4409
+ this.tagBuilder = '<';
4410
+ continue;
4411
+ }
4412
+
4413
+ // 正常字符处理
4414
+ if (this.avaterStatus === 'thinking') {
4415
+ this.currentMessage.thinking += char;
4416
+ } else {
4417
+ this.currentMessage.content += char;
4418
+ }
4419
+ }
4420
+ this.$forceUpdate();
4277
4421
  },
4278
4422
  processAudio(event) {
4279
4423
  if (!this.isRecording) return;
@@ -4370,10 +4514,10 @@ const FRAME_SIZE = 512;
4370
4514
  });
4371
4515
  ;// ./components/ChatWindow.vue?vue&type=script&lang=js
4372
4516
  /* harmony default export */ var components_ChatWindowvue_type_script_lang_js = (ChatWindowvue_type_script_lang_js);
4373
- ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-12.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindow.vue?vue&type=style&index=0&id=43521054&prod&scoped=true&lang=css
4517
+ ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-12.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindow.vue?vue&type=style&index=0&id=62955cf4&prod&scoped=true&lang=css
4374
4518
  // extracted by mini-css-extract-plugin
4375
4519
 
4376
- ;// ./components/ChatWindow.vue?vue&type=style&index=0&id=43521054&prod&scoped=true&lang=css
4520
+ ;// ./components/ChatWindow.vue?vue&type=style&index=0&id=62955cf4&prod&scoped=true&lang=css
4377
4521
 
4378
4522
  ;// ./node_modules/@vue/vue-loader-v15/lib/runtime/componentNormalizer.js
4379
4523
  /* globals __VUE_SSR_CONTEXT__ */
@@ -4488,7 +4632,7 @@ var component = normalizeComponent(
4488
4632
  staticRenderFns,
4489
4633
  false,
4490
4634
  null,
4491
- "43521054",
4635
+ "62955cf4",
4492
4636
  null
4493
4637
 
4494
4638
  )