byt-lingxiao-ai 0.3.20 → 0.3.22

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.
package/dist/index.umd.js CHANGED
@@ -1217,6 +1217,23 @@ function stylus(hljs) {
1217
1217
  }
1218
1218
  module.exports = stylus;
1219
1219
 
1220
+ /***/ }),
1221
+
1222
+ /***/ 655:
1223
+ /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
1224
+
1225
+ "use strict";
1226
+
1227
+ var classof = __webpack_require__(6955);
1228
+
1229
+ var $String = String;
1230
+
1231
+ module.exports = function (argument) {
1232
+ if (classof(argument) === 'Symbol') throw new TypeError('Cannot convert a Symbol value to a string');
1233
+ return $String(argument);
1234
+ };
1235
+
1236
+
1220
1237
  /***/ }),
1221
1238
 
1222
1239
  /***/ 679:
@@ -5774,6 +5791,21 @@ var POLYFILL = isForced.POLYFILL = 'P';
5774
5791
  module.exports = isForced;
5775
5792
 
5776
5793
 
5794
+ /***/ }),
5795
+
5796
+ /***/ 2812:
5797
+ /***/ (function(module) {
5798
+
5799
+ "use strict";
5800
+
5801
+ var $TypeError = TypeError;
5802
+
5803
+ module.exports = function (passed, required) {
5804
+ if (passed < required) throw new $TypeError('Not enough arguments');
5805
+ return passed;
5806
+ };
5807
+
5808
+
5777
5809
  /***/ }),
5778
5810
 
5779
5811
  /***/ 2839:
@@ -11813,6 +11845,63 @@ module.exports =
11813
11845
  (function () { return this; })() || Function('return this')();
11814
11846
 
11815
11847
 
11848
+ /***/ }),
11849
+
11850
+ /***/ 4603:
11851
+ /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
11852
+
11853
+ "use strict";
11854
+
11855
+ var defineBuiltIn = __webpack_require__(6840);
11856
+ var uncurryThis = __webpack_require__(9504);
11857
+ var toString = __webpack_require__(655);
11858
+ var validateArgumentsLength = __webpack_require__(2812);
11859
+
11860
+ var $URLSearchParams = URLSearchParams;
11861
+ var URLSearchParamsPrototype = $URLSearchParams.prototype;
11862
+ var append = uncurryThis(URLSearchParamsPrototype.append);
11863
+ var $delete = uncurryThis(URLSearchParamsPrototype['delete']);
11864
+ var forEach = uncurryThis(URLSearchParamsPrototype.forEach);
11865
+ var push = uncurryThis([].push);
11866
+ var params = new $URLSearchParams('a=1&a=2&b=3');
11867
+
11868
+ params['delete']('a', 1);
11869
+ // `undefined` case is a Chromium 117 bug
11870
+ // https://bugs.chromium.org/p/v8/issues/detail?id=14222
11871
+ params['delete']('b', undefined);
11872
+
11873
+ if (params + '' !== 'a=2') {
11874
+ defineBuiltIn(URLSearchParamsPrototype, 'delete', function (name /* , value */) {
11875
+ var length = arguments.length;
11876
+ var $value = length < 2 ? undefined : arguments[1];
11877
+ if (length && $value === undefined) return $delete(this, name);
11878
+ var entries = [];
11879
+ forEach(this, function (v, k) { // also validates `this`
11880
+ push(entries, { key: k, value: v });
11881
+ });
11882
+ validateArgumentsLength(length, 1);
11883
+ var key = toString(name);
11884
+ var value = toString($value);
11885
+ var index = 0;
11886
+ var dindex = 0;
11887
+ var found = false;
11888
+ var entriesLength = entries.length;
11889
+ var entry;
11890
+ while (index < entriesLength) {
11891
+ entry = entries[index++];
11892
+ if (found || entry.key === key) {
11893
+ found = true;
11894
+ $delete(this, entry.key);
11895
+ } else dindex++;
11896
+ }
11897
+ while (dindex < entriesLength) {
11898
+ entry = entries[dindex++];
11899
+ if (!(entry.key === key && entry.value === value)) append(this, entry.key, entry.value);
11900
+ }
11901
+ }, { enumerable: true, unsafe: true });
11902
+ }
11903
+
11904
+
11816
11905
  /***/ }),
11817
11906
 
11818
11907
  /***/ 4618:
@@ -21277,6 +21366,42 @@ function dsconfig(hljs) {
21277
21366
  }
21278
21367
  module.exports = dsconfig;
21279
21368
 
21369
+ /***/ }),
21370
+
21371
+ /***/ 7566:
21372
+ /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
21373
+
21374
+ "use strict";
21375
+
21376
+ var defineBuiltIn = __webpack_require__(6840);
21377
+ var uncurryThis = __webpack_require__(9504);
21378
+ var toString = __webpack_require__(655);
21379
+ var validateArgumentsLength = __webpack_require__(2812);
21380
+
21381
+ var $URLSearchParams = URLSearchParams;
21382
+ var URLSearchParamsPrototype = $URLSearchParams.prototype;
21383
+ var getAll = uncurryThis(URLSearchParamsPrototype.getAll);
21384
+ var $has = uncurryThis(URLSearchParamsPrototype.has);
21385
+ var params = new $URLSearchParams('a=1');
21386
+
21387
+ // `undefined` case is a Chromium 117 bug
21388
+ // https://bugs.chromium.org/p/v8/issues/detail?id=14222
21389
+ if (params.has('a', 2) || !params.has('a', undefined)) {
21390
+ defineBuiltIn(URLSearchParamsPrototype, 'has', function has(name /* , value */) {
21391
+ var length = arguments.length;
21392
+ var $value = length < 2 ? undefined : arguments[1];
21393
+ if (length && $value === undefined) return $has(this, name);
21394
+ var values = getAll(this, name); // also validates `this`
21395
+ validateArgumentsLength(length, 1);
21396
+ var value = toString($value);
21397
+ var index = 0;
21398
+ while (index < values.length) {
21399
+ if (values[index++] === value) return true;
21400
+ } return false;
21401
+ }, { enumerable: true, unsafe: true });
21402
+ }
21403
+
21404
+
21280
21405
  /***/ }),
21281
21406
 
21282
21407
  /***/ 7569:
@@ -24154,6 +24279,35 @@ module.exports = DESCRIPTORS && fails(function () {
24154
24279
  });
24155
24280
 
24156
24281
 
24282
+ /***/ }),
24283
+
24284
+ /***/ 8721:
24285
+ /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
24286
+
24287
+ "use strict";
24288
+
24289
+ var DESCRIPTORS = __webpack_require__(3724);
24290
+ var uncurryThis = __webpack_require__(9504);
24291
+ var defineBuiltInAccessor = __webpack_require__(2106);
24292
+
24293
+ var URLSearchParamsPrototype = URLSearchParams.prototype;
24294
+ var forEach = uncurryThis(URLSearchParamsPrototype.forEach);
24295
+
24296
+ // `URLSearchParams.prototype.size` getter
24297
+ // https://github.com/whatwg/url/pull/734
24298
+ if (DESCRIPTORS && !('size' in URLSearchParamsPrototype)) {
24299
+ defineBuiltInAccessor(URLSearchParamsPrototype, 'size', {
24300
+ get: function size() {
24301
+ var count = 0;
24302
+ forEach(this, function () { count++; });
24303
+ return count;
24304
+ },
24305
+ configurable: true,
24306
+ enumerable: true
24307
+ });
24308
+ }
24309
+
24310
+
24157
24311
  /***/ }),
24158
24312
 
24159
24313
  /***/ 8727:
@@ -29023,8 +29177,8 @@ var UserMessage_component = normalizeComponent(
29023
29177
  )
29024
29178
 
29025
29179
  /* harmony default export */ var UserMessage = (UserMessage_component.exports);
29026
- ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.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/AiMessage.vue?vue&type=template&id=c82646d8&scoped=true
29027
- var AiMessagevue_type_template_id_c82646d8_scoped_true_render = function render() {
29180
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.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/AiMessage.vue?vue&type=template&id=0d2964f2&scoped=true
29181
+ var AiMessagevue_type_template_id_0d2964f2_scoped_true_render = function render() {
29028
29182
  var _vm = this,
29029
29183
  _c = _vm._self._c;
29030
29184
  return _c('div', {
@@ -29039,26 +29193,46 @@ var AiMessagevue_type_template_id_c82646d8_scoped_true_render = function render(
29039
29193
  staticClass: "dot"
29040
29194
  }), _c('div', {
29041
29195
  staticClass: "dot"
29042
- })]) : _vm._e(), _vm.message.thinking ? _c('div', {
29043
- staticClass: "ai-thinking",
29044
- on: {
29045
- "click": function ($event) {
29046
- return _vm.$emit('thinking-toggle');
29196
+ })]) : _vm._e(), _vm._l(_vm.mergedTimeline, function (item) {
29197
+ return _c('div', {
29198
+ key: item.id,
29199
+ staticClass: "ai-timeline-item"
29200
+ }, [item.type === 'thinking' ? _c('div', {
29201
+ staticClass: "ai-thinking",
29202
+ on: {
29203
+ "click": function ($event) {
29204
+ return _vm.$emit('thinking-toggle');
29205
+ }
29047
29206
  }
29048
- }
29049
- }, [_c('div', {
29050
- staticClass: "ai-thinking-time"
29051
- }, [_vm._v(_vm._s(_vm.message.time ? `思考用时${_vm.message.time}秒` : '思考中...'))]), _vm.thinkingExpanded ? _c('div', {
29052
- staticClass: "ai-thinking-content"
29053
- }, [_vm._v(_vm._s(_vm.message.thinking))]) : _vm._e()]) : _vm._e(), _c('div', {
29054
- staticClass: "ai-content markdown-body",
29055
- domProps: {
29056
- "innerHTML": _vm._s(_vm.renderedContent)
29057
- }
29058
- })])]);
29207
+ }, [_c('div', {
29208
+ staticClass: "ai-thinking-time"
29209
+ }, [_vm._v(" " + _vm._s(_vm.message.time ? `思考用时 ${_vm.message.time} 秒` : '思考中...') + " ")]), _vm.thinkingExpanded ? _c('div', {
29210
+ staticClass: "ai-thinking-content"
29211
+ }, [_vm._v(" " + _vm._s(item.text) + " ")]) : _vm._e()]) : item.type === 'tool' ? _c('div', {
29212
+ staticClass: "ai-tool"
29213
+ }, [_c('div', {
29214
+ staticClass: "ai-tool-header"
29215
+ }, [_vm._v(" 调用工具:" + _vm._s(item.tool.name) + " ")]), _c('details', [_c('summary', [_vm._v("参数")]), _c('pre', [_vm._v(_vm._s(item.tool.args))])]), item.tool.result ? _c('details', [_c('summary', [_vm._v("结果")]), _c('pre', [_vm._v(_vm._s(item.tool.result))])]) : _vm._e()]) : item.type === 'content' ? _c('div', {
29216
+ staticClass: "ai-content markdown-body",
29217
+ domProps: {
29218
+ "innerHTML": _vm._s(_vm.renderMarkdown(item.text))
29219
+ },
29220
+ on: {
29221
+ "click": _vm.handleLinkClick
29222
+ }
29223
+ }) : _vm._e(), item.type === 'protocol_error' ? _c('div', {
29224
+ staticClass: "ai-protocol-error"
29225
+ }, [_vm._v(" " + _vm._s(item.raw) + " ")]) : _vm._e()]);
29226
+ })], 2)]);
29059
29227
  };
29060
- var AiMessagevue_type_template_id_c82646d8_scoped_true_staticRenderFns = [];
29061
-
29228
+ var AiMessagevue_type_template_id_0d2964f2_scoped_true_staticRenderFns = [];
29229
+
29230
+ // EXTERNAL MODULE: ./node_modules/core-js/modules/web.url-search-params.delete.js
29231
+ var web_url_search_params_delete = __webpack_require__(4603);
29232
+ // EXTERNAL MODULE: ./node_modules/core-js/modules/web.url-search-params.has.js
29233
+ var web_url_search_params_has = __webpack_require__(7566);
29234
+ // EXTERNAL MODULE: ./node_modules/core-js/modules/web.url-search-params.size.js
29235
+ var web_url_search_params_size = __webpack_require__(8721);
29062
29236
  ;// ./node_modules/@babel/runtime/helpers/esm/typeof.js
29063
29237
  function _typeof(o) {
29064
29238
  "@babel/helpers - typeof";
@@ -30834,26 +31008,30 @@ var lib = __webpack_require__(336);
30834
31008
 
30835
31009
 
30836
31010
 
30837
- // 创建自定义渲染器
31011
+
31012
+
31013
+
30838
31014
  const renderer = new d.Renderer();
30839
31015
 
30840
- // 自定义URL处理逻辑
30841
- // renderer.link = function(content) {
30842
- // console.log(content)
30843
- // return `<router-link to="http://192.168.2.24:9529/portal/permission/user">点击跳转</router-link>`
30844
- // };
31016
+ // 自定义链接渲染
30845
31017
  renderer.link = function ({
30846
31018
  href,
30847
- title
31019
+ text
30848
31020
  }) {
30849
- console.log(href, title);
30850
- // 需要截取portal后面的路径
30851
- const url = `/permission/user`;
30852
- return `<a href="${url}" data-path="${url}">点击跳转</a>`;
31021
+ let dataPath = '';
31022
+ const url = new URL(href, window.location.origin);
31023
+ const pathname = url.pathname;
31024
+ if (pathname.startsWith('/portal/')) {
31025
+ dataPath = pathname.substring('/portal'.length);
31026
+ return `<a href="javascript:void(0)" data-path="${dataPath}" data-text="${text}">${text}</a>`;
31027
+ } else {
31028
+ dataPath = href;
31029
+ return `<a href="${dataPath}" target="_blank">${text}</a>`;
31030
+ }
30853
31031
  };
30854
31032
  d.setOptions({
30855
- renderer: renderer,
30856
- highlight: function (code, lang) {
31033
+ renderer,
31034
+ highlight(code, lang) {
30857
31035
  if (lang && es.getLanguage(lang)) {
30858
31036
  return es.highlight(code, {
30859
31037
  language: lang
@@ -30876,25 +31054,67 @@ d.setOptions({
30876
31054
  thinkingExpanded() {
30877
31055
  return this.message.thinkingExpanded !== false;
30878
31056
  },
30879
- renderedContent() {
30880
- return d.parse(this.message.content || '');
30881
- },
30882
31057
  isLoading() {
30883
31058
  return this.message.loading === true;
31059
+ },
31060
+ mergedTimeline() {
31061
+ const result = [];
31062
+ let last = null;
31063
+ for (const item of this.message.timeline || []) {
31064
+ if (item.type === 'content') {
31065
+ if (last && last.type === 'content') {
31066
+ last.text += item.text;
31067
+ } else {
31068
+ last = {
31069
+ ...item
31070
+ };
31071
+ result.push(last);
31072
+ }
31073
+ } else {
31074
+ last = null;
31075
+ result.push(item);
31076
+ }
31077
+ }
31078
+ return result;
30884
31079
  }
30885
31080
  },
30886
- watch: {
30887
- thinkStatus(newVal, oldVal) {
30888
- console.log('thinkStatus 变化:', newVal, oldVal);
31081
+ methods: {
31082
+ renderMarkdown(text) {
31083
+ return d.parse(text || '');
31084
+ },
31085
+ handleLinkClick(event) {
31086
+ const link = event.target.closest('a');
31087
+ if (!link) return;
31088
+ const routePath = link.getAttribute('data-path');
31089
+ const linkText = link.getAttribute('data-text');
31090
+ if (routePath && linkText) {
31091
+ event.preventDefault();
31092
+ if (this.$appOptions?.store?.dispatch) {
31093
+ this.$appOptions.store.dispatch('tags/addTagview', {
31094
+ path: routePath,
31095
+ fullPath: routePath,
31096
+ label: linkText,
31097
+ name: linkText,
31098
+ meta: {
31099
+ title: linkText
31100
+ }
31101
+ });
31102
+ this.$appOptions.router.push({
31103
+ path: routePath
31104
+ });
31105
+ } else {
31106
+ this.$router.push(routePath).catch(() => {});
31107
+ }
31108
+ }
30889
31109
  }
30890
31110
  }
30891
31111
  });
30892
31112
  ;// ./components/AiMessage.vue?vue&type=script&lang=js
30893
31113
  /* harmony default export */ var components_AiMessagevue_type_script_lang_js = (AiMessagevue_type_script_lang_js);
30894
- ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-54.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-54.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-54.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/AiMessage.vue?vue&type=style&index=0&id=c82646d8&prod&scoped=true&lang=css
31114
+ ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-54.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-54.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-54.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/AiMessage.vue?vue&type=style&index=0&id=0d2964f2&prod&scoped=true&lang=css
30895
31115
  // extracted by mini-css-extract-plugin
30896
31116
 
30897
- ;// ./components/AiMessage.vue?vue&type=style&index=0&id=c82646d8&prod&scoped=true&lang=css
31117
+ ;// ./components/AiMessage.vue?vue&type=style&index=0&id=0d2964f2&prod&scoped=true&lang=css
30898
31118
 
30899
31119
  ;// ./components/AiMessage.vue
30900
31120
 
@@ -30907,11 +31127,11 @@ d.setOptions({
30907
31127
 
30908
31128
  var AiMessage_component = normalizeComponent(
30909
31129
  components_AiMessagevue_type_script_lang_js,
30910
- AiMessagevue_type_template_id_c82646d8_scoped_true_render,
30911
- AiMessagevue_type_template_id_c82646d8_scoped_true_staticRenderFns,
31130
+ AiMessagevue_type_template_id_0d2964f2_scoped_true_render,
31131
+ AiMessagevue_type_template_id_0d2964f2_scoped_true_staticRenderFns,
30912
31132
  false,
30913
31133
  null,
30914
- "c82646d8",
31134
+ "0d2964f2",
30915
31135
  null
30916
31136
 
30917
31137
  )
@@ -31432,99 +31652,138 @@ const TIME_JUMP_POINTS_URL = '/minio/lingxiaoai/timeJumpPoints.json'; // 语音u
31432
31652
  });
31433
31653
  ;// ./components/utils/StreamParser.js
31434
31654
 
31655
+ // utils/StreamParser.js
31435
31656
  class StreamParser {
31436
31657
  constructor(options = {}) {
31437
31658
  this.options = {
31438
31659
  updateInterval: 16,
31439
- // 每16ms刷新一次(约60fps)
31440
31660
  debug: false,
31441
31661
  ...options
31442
31662
  };
31443
31663
  this.reset();
31444
31664
  }
31445
-
31446
- // 重置解析器状态
31447
31665
  reset() {
31448
- this.buffer = '';
31449
31666
  this.contentBuffer = [];
31450
31667
  this.thinkingBuffer = [];
31668
+ this.completedThinkingSegments = [];
31669
+ this.completedToolCalls = [];
31670
+ this.currentToolCall = null;
31671
+ this.protocolErrorBuffer = []; // ✅ 新增
31672
+
31451
31673
  this.inTag = false;
31452
31674
  this.tagBuffer = '';
31453
31675
  this.updateTimer = null;
31454
- this.status = 'output'; // thinking | output
31676
+ this.status = 'output'; // thinking | output | tool_call | tool_result
31455
31677
  }
31456
-
31457
- // 处理接收到的流数据块
31458
31678
  processChunk(chunk, callback) {
31459
31679
  if (!chunk) return;
31460
31680
  this.parseContent(chunk, callback);
31461
31681
  }
31462
-
31463
- // 核心内容解析,支持 <think> 标签
31464
31682
  parseContent(content, callback) {
31465
31683
  let i = 0;
31466
31684
  while (i < content.length) {
31467
31685
  if (this.inTag) {
31468
- const endIndex = content.indexOf('>', i);
31469
- if (endIndex !== -1) {
31470
- this.tagBuffer += content.substring(i, endIndex + 1);
31686
+ const end = content.indexOf('>', i);
31687
+ if (end !== -1) {
31688
+ this.tagBuffer += content.slice(i, end + 1);
31471
31689
  this.handleTag(this.tagBuffer);
31472
31690
  this.tagBuffer = '';
31473
31691
  this.inTag = false;
31474
- i = endIndex + 1;
31692
+ i = end + 1;
31475
31693
  } else {
31476
- // 标签未闭合,超过50字符强制输出,防止阻塞
31477
- this.tagBuffer += content.substring(i);
31478
- if (this.tagBuffer.length > 50) {
31479
- this.appendText(this.tagBuffer);
31480
- this.tagBuffer = '';
31481
- this.inTag = false;
31482
- }
31694
+ this.tagBuffer += content.slice(i);
31483
31695
  break;
31484
31696
  }
31485
31697
  } else {
31486
- const startIndex = content.indexOf('<', i);
31487
- if (startIndex !== -1) {
31488
- if (startIndex > i) this.appendText(content.substring(i, startIndex));
31489
- const endIndex = content.indexOf('>', startIndex);
31490
- if (endIndex !== -1) {
31491
- const tag = content.substring(startIndex, endIndex + 1);
31492
- this.handleTag(tag);
31493
- i = endIndex + 1;
31494
- } else {
31495
- const nextChar = content[startIndex + 1];
31496
- if (!/[a-zA-Z/]/.test(nextChar)) {
31497
- // 很可能不是标签,直接当文本输出
31498
- this.appendText('<');
31499
- i = startIndex + 1;
31500
- } else {
31501
- this.inTag = true;
31502
- this.tagBuffer = content.substring(startIndex);
31503
- break;
31504
- }
31505
- }
31506
- } else {
31507
- this.appendText(content.substring(i));
31698
+ const start = content.indexOf('<', i);
31699
+ if (start === -1) {
31700
+ this.appendText(content.slice(i));
31701
+ break;
31702
+ }
31703
+ if (start > i) {
31704
+ this.appendText(content.slice(i, start));
31705
+ }
31706
+ const end = content.indexOf('>', start);
31707
+ if (end === -1) {
31708
+ this.inTag = true;
31709
+ this.tagBuffer = content.slice(start);
31508
31710
  break;
31509
31711
  }
31712
+ const tag = content.slice(start, end + 1);
31713
+ this.handleTag(tag);
31714
+ i = end + 1;
31510
31715
  }
31511
31716
  }
31512
31717
  this.scheduleUpdate(callback);
31513
31718
  }
31514
-
31515
- // 处理标签
31516
31719
  handleTag(tag) {
31517
31720
  const t = tag.toLowerCase();
31518
- if (t === '<think>') this.status = 'thinking';else if (t === '</think>') this.status = 'output';
31519
- }
31520
31721
 
31521
- // 添加文本到缓冲区
31722
+ // ---------- think ----------
31723
+ if (t === '<think>') {
31724
+ this.status = 'thinking';
31725
+ return;
31726
+ }
31727
+ if (t === '</think>') {
31728
+ if (this.thinkingBuffer.length) {
31729
+ this.completedThinkingSegments.push(this.thinkingBuffer.join(''));
31730
+ this.thinkingBuffer = [];
31731
+ }
31732
+ this.status = 'output';
31733
+ return;
31734
+ }
31735
+
31736
+ // ---------- tool_call ----------
31737
+ if (t.startsWith('<tool_call')) {
31738
+ const nameMatch = tag.match(/name\s*=\s*["'](.+?)["']/);
31739
+ this.currentToolCall = {
31740
+ id: `${Date.now()}-${Math.random()}`,
31741
+ name: nameMatch ? nameMatch[1] : 'unknown',
31742
+ args: '',
31743
+ result: '',
31744
+ status: 'calling'
31745
+ };
31746
+ this.status = 'tool_call';
31747
+ return;
31748
+ }
31749
+ if (t === '</tool_call>') {
31750
+ this.status = 'output';
31751
+ return;
31752
+ }
31753
+
31754
+ // ---------- tool_result ----------
31755
+ if (t === '<tool_result>') {
31756
+ this.status = 'tool_result';
31757
+ return;
31758
+ }
31759
+ if (t === '</tool_result>') {
31760
+ if (this.currentToolCall) {
31761
+ this.currentToolCall.status = 'done';
31762
+ this.completedToolCalls.push(this.currentToolCall);
31763
+ this.currentToolCall = null;
31764
+ }
31765
+ this.status = 'output';
31766
+ return;
31767
+ }
31768
+
31769
+ // ---------- ❌ 协议错误 ----------
31770
+ if (t.startsWith('<') && t.endsWith('>')) {
31771
+ this.protocolErrorBuffer.push(tag);
31772
+ this.status = 'output';
31773
+ }
31774
+ }
31522
31775
  appendText(text) {
31523
31776
  if (!text) return;
31524
- if (this.status === 'thinking') this.thinkingBuffer.push(text);else this.contentBuffer.push(text);
31777
+ if (this.status === 'thinking') {
31778
+ this.thinkingBuffer.push(text);
31779
+ } else if (this.status === 'tool_call') {
31780
+ this.currentToolCall && (this.currentToolCall.args += text);
31781
+ } else if (this.status === 'tool_result') {
31782
+ this.currentToolCall && (this.currentToolCall.result += text);
31783
+ } else {
31784
+ this.contentBuffer.push(text);
31785
+ }
31525
31786
  }
31526
-
31527
- // 防抖刷新
31528
31787
  scheduleUpdate(callback) {
31529
31788
  if (this.updateTimer) return;
31530
31789
  this.updateTimer = setTimeout(() => {
@@ -31532,32 +31791,39 @@ class StreamParser {
31532
31791
  this.updateTimer = null;
31533
31792
  }, this.options.updateInterval);
31534
31793
  }
31535
-
31536
- // 刷新缓冲区
31537
31794
  flush(callback) {
31538
31795
  if (!callback) return;
31539
31796
  const result = {
31540
- thinking: this.thinkingBuffer.length ? this.thinkingBuffer.join('') : null,
31541
- content: this.contentBuffer.length ? this.contentBuffer.join('') : null,
31797
+ thinkingSegment: null,
31798
+ toolCall: null,
31799
+ content: null,
31800
+ protocolError: null,
31542
31801
  status: this.status
31543
31802
  };
31544
- this.thinkingBuffer = [];
31545
- this.contentBuffer = [];
31803
+ if (this.protocolErrorBuffer.length) {
31804
+ result.protocolError = this.protocolErrorBuffer.join('\n');
31805
+ this.protocolErrorBuffer = [];
31806
+ }
31807
+ if (this.completedThinkingSegments.length) {
31808
+ result.thinkingSegment = this.completedThinkingSegments.shift();
31809
+ }
31810
+ if (this.completedToolCalls.length) {
31811
+ result.toolCall = this.completedToolCalls.shift();
31812
+ }
31813
+ if (this.contentBuffer.length) {
31814
+ result.content = this.contentBuffer.join('');
31815
+ this.contentBuffer = [];
31816
+ }
31546
31817
  callback(result);
31547
31818
  }
31548
-
31549
- // 完成解析
31550
31819
  finish(callback) {
31551
- if (this.inTag && this.tagBuffer) {
31552
- this.appendText(this.tagBuffer);
31553
- this.tagBuffer = '';
31554
- this.inTag = false;
31820
+ if (this.thinkingBuffer.length) {
31821
+ this.completedThinkingSegments.push(this.thinkingBuffer.join(''));
31822
+ this.thinkingBuffer = [];
31555
31823
  }
31556
31824
  this.flush(callback);
31557
31825
  if (this.updateTimer) clearTimeout(this.updateTimer);
31558
31826
  }
31559
-
31560
- // 销毁解析器
31561
31827
  destroy() {
31562
31828
  if (this.updateTimer) clearTimeout(this.updateTimer);
31563
31829
  this.reset();
@@ -31607,9 +31873,7 @@ const getCookie = cname => {
31607
31873
  type: 'ai',
31608
31874
  sender: 'AI',
31609
31875
  time: '',
31610
- thinking: '',
31611
- charts: [],
31612
- content: '',
31876
+ timeline: [],
31613
31877
  loading: true,
31614
31878
  thinkingExpanded: true
31615
31879
  };
@@ -31642,7 +31906,7 @@ const getCookie = cname => {
31642
31906
  const controller = new AbortController();
31643
31907
  try {
31644
31908
  const startTime = Date.now();
31645
- const token = getCookie('bonyear-access_token') || `44e7f112-63f3-429d-908d-2c97ec380de2`;
31909
+ const token = getCookie('bonyear-access_token') || `b6dd936e-4b8b-4e10-ba70-573eb35673f1`;
31646
31910
  const response = await fetch(API_URL, {
31647
31911
  method: 'POST',
31648
31912
  signal: controller.signal,
@@ -31722,27 +31986,38 @@ const getCookie = cname => {
31722
31986
  */
31723
31987
  handleStreamUpdate(result) {
31724
31988
  if (!this.currentMessage) return;
31725
- console.log('收到更新:', result);
31726
- if (this.currentMessage.loading) {
31727
- this.currentMessage.loading = false;
31989
+ this.currentMessage.loading = false;
31990
+ if (result.protocolError) {
31991
+ this.currentMessage.timeline.push({
31992
+ type: 'protocol_error',
31993
+ id: Date.now() + Math.random(),
31994
+ raw: result.protocolError
31995
+ });
31728
31996
  }
31729
- // 更新思考内容
31730
- if (result.thinking) {
31731
- this.currentMessage.thinking += result.thinking;
31997
+ if (result.thinkingSegment) {
31998
+ this.currentMessage.timeline.push({
31999
+ type: 'thinking',
32000
+ id: Date.now() + Math.random(),
32001
+ text: result.thinkingSegment
32002
+ });
32003
+ }
32004
+ if (result.toolCall) {
32005
+ this.currentMessage.timeline.push({
32006
+ type: 'tool',
32007
+ id: result.toolCall.id,
32008
+ tool: result.toolCall
32009
+ });
31732
32010
  }
31733
-
31734
- // 更新回复内容
31735
- console.log('更新回复内容:', result.content);
31736
32011
  if (result.content) {
31737
- this.currentMessage.content += result.content;
32012
+ this.currentMessage.timeline.push({
32013
+ type: 'content',
32014
+ id: Date.now() + Math.random(),
32015
+ text: result.content
32016
+ });
31738
32017
  }
31739
32018
 
31740
32019
  // 更新状态
31741
- if (result.status === 'thinking') {
31742
- this.avaterStatus = 'thinking';
31743
- } else {
31744
- this.avaterStatus = 'output';
31745
- }
32020
+ this.avaterStatus = result.status === 'thinking' ? 'thinking' : 'output';
31746
32021
 
31747
32022
  // 触发视图更新
31748
32023
  this.$forceUpdate();