inl-ui 0.1.3 → 0.1.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.
@@ -11231,18 +11231,152 @@ const SszComment = vue.defineComponent({
11231
11231
  });
11232
11232
  var index = installComponent(SszComment, "ssz-comment");
11233
11233
 
11234
+ function formatDataString(str) {
11235
+ const lines = str.split("\n");
11236
+ const result = lines.filter(line => !!line.trim()).map(line => {
11237
+ const data = JSON.parse(line.replace(/^data: /, ""));
11238
+ return data.text;
11239
+ }).filter(line => line !== void 0).join("");
11240
+ return result;
11241
+ }
11242
+ function request(question, streamCallback, doneCallback) {
11243
+ const controller = new AbortController();
11244
+ const signal = controller.signal;
11245
+ fetch("/mt_cpp_gpt/chat", {
11246
+ signal,
11247
+ method: "POST",
11248
+ headers: {
11249
+ "Content-Type": "application/json"
11250
+ },
11251
+ body: JSON.stringify({
11252
+ query: question,
11253
+ conversation_id: ""
11254
+ })
11255
+ }).then(res => {
11256
+ const stream = res.body;
11257
+ const decoder = new TextDecoder();
11258
+ const reader = stream.getReader();
11259
+ let result = "";
11260
+ function processText() {
11261
+ return reader.read().then(({
11262
+ done,
11263
+ value
11264
+ }) => {
11265
+ if (done) {
11266
+ doneCallback();
11267
+ return;
11268
+ }
11269
+ try {
11270
+ const dataString = decoder.decode(value, {
11271
+ stream: true
11272
+ });
11273
+ const str = formatDataString(dataString);
11274
+ result += str;
11275
+ streamCallback(result);
11276
+ } catch (e) {}
11277
+ return processText();
11278
+ }).catch(() => {
11279
+ doneCallback();
11280
+ });
11281
+ }
11282
+ return processText();
11283
+ }).catch(() => {
11284
+ doneCallback();
11285
+ });
11286
+ return function stop() {
11287
+ controller.abort();
11288
+ };
11289
+ }
11290
+ function useQA() {
11291
+ const context = vue.ref([]);
11292
+ const answerLoading = vue.ref(false);
11293
+ const answer = vue.ref("");
11294
+ let abort = null;
11295
+ setTimeout(() => {
11296
+ const questionItem = {
11297
+ type: "answer",
11298
+ content: "",
11299
+ id: /* @__PURE__ */new Date().getTime(),
11300
+ timestamp: /* @__PURE__ */new Date().getTime(),
11301
+ answers: [{
11302
+ content: "\u4F60\u597D\uFF0C\u6211\u662F\u4F60\u7684\u5DE5\u4F5C\u4F19\u4F34 \u7F8E\u5C0F\u817E! \u6211\u53EF\u4EE5\u8F85\u52A9\u4F60\u5FEB\u901F\u83B7\u53D6\u4FE1\u606F\uFF0C\u76D1\u63A7\u3001\u67E5\u770B\u751F\u4EA7\u6307\u6807\uFF0C\u56DE\u7B54\u60A8\u7684\u9009\u7164\u4E13\u4E1A\u95EE\u9898\uFF0C\u5FEB\u8BD5\u8BD5\u4E0B\u9762\u5BF9\u8BDD\u5427\u3002",
11303
+ timestamp: /* @__PURE__ */new Date().getTime(),
11304
+ hideOperates: true,
11305
+ id: /* @__PURE__ */new Date().getTime()
11306
+ }]
11307
+ };
11308
+ context.value.push(questionItem);
11309
+ }, 1e3);
11310
+ function sendQuestion(question, questionId) {
11311
+ if (answerLoading.value) return;
11312
+ answerLoading.value = true;
11313
+ let questionItem = context.value.find(item => item.id === questionId);
11314
+ question = questionItem?.content || question;
11315
+ if (!questionId) {
11316
+ questionItem = {
11317
+ id: /* @__PURE__ */new Date().getTime(),
11318
+ timestamp: /* @__PURE__ */new Date().getTime(),
11319
+ content: question,
11320
+ answers: []
11321
+ };
11322
+ context.value.push(questionItem);
11323
+ }
11324
+ const answerItem = vue.ref({
11325
+ content: "\u6B63\u5728\u601D\u8003\u4E2D...",
11326
+ timestamp: /* @__PURE__ */new Date().getTime(),
11327
+ parentId: questionItem.id,
11328
+ id: /* @__PURE__ */new Date().getTime()
11329
+ });
11330
+ questionItem.answers.push(answerItem.value);
11331
+ abort = request(question, data => {
11332
+ answer.value = data;
11333
+ answerItem.value.content = data;
11334
+ }, () => {
11335
+ answerLoading.value = false;
11336
+ answerItem.value.loadEnd = true;
11337
+ abort = null;
11338
+ });
11339
+ }
11340
+ function abortRequest() {
11341
+ if (abort) {
11342
+ abort();
11343
+ abort = null;
11344
+ }
11345
+ }
11346
+ return {
11347
+ context,
11348
+ answerLoading,
11349
+ answer,
11350
+ sendQuestion,
11351
+ abortRequest
11352
+ };
11353
+ }
11354
+
11234
11355
  const Input = vue.defineComponent({
11235
11356
  emits: ["send"],
11236
11357
  setup(props, {
11237
11358
  emit,
11238
11359
  expose
11239
11360
  }) {
11361
+ const abortRequest = vue.inject("abortRequest");
11362
+ const loading = vue.inject("answerLoading");
11240
11363
  const value = vue.ref("");
11241
11364
  const isFocus = vue.ref(false);
11242
11365
  const send = () => {
11366
+ if (loading.value) return;
11367
+ if (value.value.length === 0) {
11368
+ antDesignVue.message.warn("\u8BF7\u8F93\u5165\u95EE\u9898");
11369
+ return;
11370
+ }
11243
11371
  emit("send", value.value);
11244
11372
  value.value = "";
11245
11373
  };
11374
+ const handleAbord = () => {
11375
+ abortRequest();
11376
+ };
11377
+ const handleMicClick = () => {
11378
+ antDesignVue.message.info("\u6682\u4E0D\u652F\u6301\u8BED\u97F3\u8F93\u5165");
11379
+ };
11246
11380
  const clear = () => value.value = "";
11247
11381
  expose({
11248
11382
  clear
@@ -11251,14 +11385,26 @@ const Input = vue.defineComponent({
11251
11385
  "class": ["chat-box-input", {
11252
11386
  focus: isFocus.value
11253
11387
  }]
11254
- }, [vue.createVNode(iconsVue.AudioFilled, null, null), vue.createVNode(vue.resolveComponent("a-input"), {
11388
+ }, [vue.createVNode("img", {
11389
+ "class": "img img-mic",
11390
+ "src": "/micro-assets/largeLanguageModel/mic.png",
11391
+ "alt": "",
11392
+ "onClick": handleMicClick
11393
+ }, null), vue.createVNode(vue.resolveComponent("a-input"), {
11255
11394
  "value": value.value,
11256
11395
  "onUpdate:value": $event => value.value = $event,
11257
11396
  "bordered": false,
11258
11397
  "placeholder": "\u5982: \u67E5\u770BXXX\u76AE\u5E26\u673A\u5934\u7535\u6D41\u7B49",
11259
11398
  "onFocus": () => isFocus.value = true,
11260
- "onBlur": () => isFocus.value = false
11261
- }, null), vue.createVNode(iconsVue.SendOutlined, {
11399
+ "onBlur": () => isFocus.value = false,
11400
+ "onPressEnter": send
11401
+ }, null), loading.value ? vue.createVNode(iconsVue.BorderOutlined, {
11402
+ "class": "btn-abord",
11403
+ "title": "\u4E2D\u6B62\u56DE\u7B54",
11404
+ "onClick": handleAbord
11405
+ }, null) : vue.createVNode("img", {
11406
+ "class": "img img-send",
11407
+ "src": "/micro-assets/largeLanguageModel/send.png",
11262
11408
  "onClick": send
11263
11409
  }, null)]);
11264
11410
  }
@@ -11266,15 +11412,19 @@ const Input = vue.defineComponent({
11266
11412
 
11267
11413
  const tips = ["\u8BBE\u5907\u5DE5\u4F5C\u539F\u7406", "\u8BBE\u5907\u7EF4\u4FDD\u624B\u518C"];
11268
11414
  const Bottom = vue.defineComponent({
11269
- setup() {
11415
+ emits: ["send"],
11416
+ setup(props, {
11417
+ emit
11418
+ }) {
11270
11419
  const inputRef = vue.ref();
11271
11420
  const handleSend = msg => {
11272
11421
  inputRef.value.clear();
11422
+ emit("send", msg);
11273
11423
  };
11274
11424
  return () => {
11275
11425
  const tipsDom = tips.map(tip => vue.createVNode("div", {
11276
11426
  "class": "tip",
11277
- "onClick": () => handleSend()
11427
+ "onClick": () => handleSend(tip)
11278
11428
  }, [tip]));
11279
11429
  return vue.createVNode("div", {
11280
11430
  "class": "bottom"
@@ -11319,12 +11469,40 @@ const Avatar = vue.defineComponent({
11319
11469
  }
11320
11470
  });
11321
11471
 
11322
- const styleDark = `
11323
- <style>
11324
- :host > p {
11325
- margin: 0;
11472
+ const QuestionBubble = vue.defineComponent({
11473
+ props: {
11474
+ content: {
11475
+ type: String,
11476
+ default: ""
11326
11477
  }
11478
+ },
11479
+ setup(props) {
11480
+ const userinfo = JSON.parse(sessionStorage.getItem("userinfo") || "{}");
11481
+ const avatar = userinfo.photo || "/micro-assets/platform_app/avatar.png";
11482
+ const name = userinfo.employeeName || userinfo.userName || "\u7528\u6237";
11483
+ return () => vue.createVNode("div", {
11484
+ "class": "question-bubble chat-bubble"
11485
+ }, [vue.createVNode(Avatar, {
11486
+ "reverse": true,
11487
+ "avatar": avatar,
11488
+ "name": name
11489
+ }, null), vue.createVNode("div", {
11490
+ "class": "bubble question"
11491
+ }, [props.content]), vue.createVNode("div", {
11492
+ "class": "operates"
11493
+ }, null)]);
11494
+ }
11495
+ });
11327
11496
 
11497
+ const commonStyle = `
11498
+ :host > p {
11499
+ margin: 0;
11500
+ }
11501
+ `;
11502
+ const styleDark = `
11503
+ <style>
11504
+ ${commonStyle}
11505
+
11328
11506
  * {
11329
11507
  color: #fff;
11330
11508
  }
@@ -11335,6 +11513,8 @@ const styleDark = `
11335
11513
  `;
11336
11514
  const styleLight = `
11337
11515
  <style>
11516
+ ${commonStyle}
11517
+
11338
11518
  * {
11339
11519
  color: #20242B;
11340
11520
  }
@@ -11346,25 +11526,26 @@ const styleLight = `
11346
11526
 
11347
11527
  const suggestionList = ["\u7F8E\u5C0F\u817E\u80FD\u5E2E\u6211\u505A\u4EC0\u4E48\uFF1F", "\u8FD1\u4E00\u4E2A\u6708\u7684\u4ECB\u8017\u60C5\u51B5\u5982\u4F55\uFF1F", "\u5C3E\u77FF\u8DD1\u7C97\u7684\u6392\u67E5\u5904\u7406\u65B9\u6CD5\u6709\u54EA\u4E9B\uFF1F\u5C3E\u77FF\u8DD1\u7C97\u7684\u6392\u67E5\u5904\u7406\u65B9\u6CD5\u6709\u54EA\u4E9B\u5C3E\u77FF\u8DD1\u7C97\u7684\u6392\u67E5\u5904\u7406\u65B9\u6CD5\u6709\u54EA\u4E9B\u5C3E\u77FF\u8DD1\u7C97\u7684\u6392\u67E5\u5904\u7406\u65B9\u6CD5\u6709\u54EA\u4E9B"];
11348
11528
  const AnswerBubble = vue.defineComponent({
11529
+ emits: ["send", "render", "delete", "regenerate"],
11530
+ props: {
11531
+ content: {
11532
+ type: Array,
11533
+ default: () => []
11534
+ }
11535
+ },
11349
11536
  setup(props, {
11350
11537
  emit
11351
11538
  }) {
11352
11539
  const chatTheme = vue.inject("chat-theme");
11540
+ const {
11541
+ copy
11542
+ } = core.useClipboard({
11543
+ legacy: true
11544
+ });
11353
11545
  const bubbleRef = vue.ref();
11546
+ const activeAnswerIndex = vue.ref(0);
11547
+ const activeAnswer = vue.computed(() => props.content[activeAnswerIndex.value]);
11354
11548
  let shadowRoot;
11355
- const mdText = vue.ref(`\u4ECA\u5929\u7684\u7CBE\u7164\u4EA7\u91CF**18830.0**\u5428\uFF0C\u672B\u7164\u4EA7\u91CF**15900.0**\u5428\uFF0C\u7164\u6CE5**539.0**\u5428
11356
-
11357
- #### \u4F60\u597D\u554A
11358
-
11359
- 1. \u4F60\u597D\u554A
11360
-
11361
- 2. \u4E09\u5929\u4E4B\u5185\u6740\u4E86\u4F60
11362
-
11363
- 3. \u4F60\u662F\u771F\u6CA1\u89C1\u8FC7\u9ED1\u793E\u4F1A\u554A
11364
-
11365
- 4. \u6562\u4E0D\u6562\u8DDF\u6211\u6BD4\u5212\u6BD4\u5212
11366
-
11367
- 5. \u8BA9\u4F60\u89C1\u8BC6\u89C1\u8BC6\u4EC0\u4E48\u53EB\u9ED1\u624B`);
11368
11549
  const trasformMd = mdString => {
11369
11550
  return marked.marked(mdString);
11370
11551
  };
@@ -11372,49 +11553,199 @@ const AnswerBubble = vue.defineComponent({
11372
11553
  shadowRoot = bubbleRef.value.attachShadow({
11373
11554
  mode: "open"
11374
11555
  });
11556
+ renderText();
11557
+ });
11558
+ const renderText = () => {
11559
+ if (!shadowRoot) return;
11560
+ vue.nextTick(() => {
11561
+ emit("render", activeAnswer.value.content);
11562
+ });
11375
11563
  const themeStyle = chatTheme === "dark" ? styleDark : styleLight;
11376
11564
  const html = `
11377
- ${trasformMd(mdText.value)}
11565
+ ${trasformMd(activeAnswer.value.content)}
11378
11566
 
11379
11567
  ${themeStyle}
11380
11568
  `;
11381
11569
  shadowRoot.innerHTML = html;
11570
+ };
11571
+ vue.watch([activeAnswer, activeAnswerIndex], renderText, {
11572
+ deep: true
11382
11573
  });
11574
+ const switchAnswer = step => {
11575
+ activeAnswerIndex.value += step;
11576
+ };
11577
+ const operateList = vue.reactive([{
11578
+ title: "\u590D\u5236",
11579
+ key: "copy",
11580
+ isActive: false
11581
+ }, {
11582
+ title: "\u6709\u7528",
11583
+ key: "like",
11584
+ isActive: vue.computed(() => activeAnswer.value.isLike)
11585
+ }, {
11586
+ title: "\u65E0\u7528",
11587
+ key: "dislike",
11588
+ isActive: vue.computed(() => activeAnswer.value.isDislike)
11589
+ }, {
11590
+ title: "\u8BC4\u8BBA",
11591
+ key: "comment",
11592
+ isActive: false
11593
+ }, {
11594
+ title: "\u91CD\u65B0\u751F\u6210",
11595
+ key: "regenerate",
11596
+ isActive: false
11597
+ }, {
11598
+ ttile: "\u5220\u9664",
11599
+ key: "delete",
11600
+ isActive: false
11601
+ }]);
11602
+ const handleOperate = key => {
11603
+ switch (key) {
11604
+ case "like":
11605
+ if (!activeAnswer.value.isDislike && !activeAnswer.value.isDislike) {
11606
+ activeAnswer.value.isLike = !activeAnswer.value.isLike;
11607
+ }
11608
+ break;
11609
+ case "dislike":
11610
+ if (!activeAnswer.value.isLike && !activeAnswer.value.isDislike) {
11611
+ activeAnswer.value.isDislike = !activeAnswer.value.isDislike;
11612
+ }
11613
+ break;
11614
+ case "copy":
11615
+ copy(activeAnswer.value.content);
11616
+ antDesignVue.message.success("\u590D\u5236\u6210\u529F");
11617
+ break;
11618
+ case "delete":
11619
+ antDesignVue.Modal.confirm({
11620
+ title: "\u786E\u5B9A\u5220\u9664\u8FD9\u4E2A\u56DE\u7B54\u5417\uFF1F",
11621
+ onOk: () => {
11622
+ emit("delete", activeAnswer.value.id);
11623
+ if (activeAnswerIndex.value > 0 && activeAnswerIndex.value === props.content.length - 1) {
11624
+ activeAnswerIndex.value--;
11625
+ }
11626
+ }
11627
+ });
11628
+ break;
11629
+ case "comment":
11630
+ antDesignVue.message.info("\u6682\u672A\u5F00\u653E");
11631
+ break;
11632
+ case "regenerate":
11633
+ if (props.content.length >= 5) {
11634
+ antDesignVue.message.info("\u6700\u591A\u652F\u6301\u751F\u62105\u6761\u56DE\u7B54");
11635
+ return;
11636
+ }
11637
+ emit("regenerate", activeAnswer.value.id);
11638
+ vue.nextTick(() => {
11639
+ activeAnswerIndex.value = props.content.length - 1;
11640
+ });
11641
+ break;
11642
+ }
11643
+ };
11383
11644
  return () => {
11384
- const suggestionListDom = suggestionList.map(item => vue.createVNode("div", {
11645
+ suggestionList.map(item => vue.createVNode("div", {
11385
11646
  "class": "suggestion-item",
11386
11647
  "onClick": () => emit("send", item)
11387
11648
  }, [item]));
11649
+ const showOperates = !activeAnswer.value.hideOperates && activeAnswer.value.loadEnd;
11650
+ const operateDom = operateList.map(item => vue.createVNode(vue.resolveComponent("a-tooltip"), {
11651
+ "title": item.title
11652
+ }, {
11653
+ default: () => [vue.createVNode("div", {
11654
+ "class": ["operate-item", item.key, {
11655
+ active: item.isActive
11656
+ }],
11657
+ "onClick": () => handleOperate(item.key)
11658
+ }, null)]
11659
+ }));
11660
+ const prevDisabled = activeAnswerIndex.value === 0;
11661
+ const nextDisabled = activeAnswerIndex.value === props.content.length - 1;
11662
+ const answerNav = vue.createVNode("div", {
11663
+ "class": "operate-item operate-nav"
11664
+ }, [vue.createVNode("span", {
11665
+ "class": ["nav", {
11666
+ disabled: prevDisabled
11667
+ }],
11668
+ "onClick": () => switchAnswer(-1)
11669
+ }, ["<"]), vue.createVNode("span", null, [activeAnswerIndex.value + 1]), " ", vue.createVNode("span", null, [vue.createTextVNode("/")]), vue.createVNode("span", null, [props.content.length]), vue.createVNode("span", {
11670
+ "class": ["nav", {
11671
+ disabled: nextDisabled
11672
+ }],
11673
+ "onClick": () => switchAnswer(1)
11674
+ }, [">"])]);
11388
11675
  return vue.createVNode("div", {
11389
11676
  "class": "answer-bubble chat-bubble"
11390
11677
  }, [vue.createVNode(Avatar, {
11391
- "avatar": "",
11678
+ "avatar": "/micro-assets/largeLanguageModel/robot-avatar.png",
11392
11679
  "name": "\u7F8E\u5C0F\u817E"
11393
11680
  }, null), vue.createVNode("div", {
11394
11681
  "ref": bubbleRef,
11395
11682
  "class": "bubble answer"
11396
11683
  }, null), vue.createVNode("div", {
11397
11684
  "class": "operates"
11398
- }, null), vue.createVNode("div", {
11399
- "class": "suggestion-list"
11400
- }, [suggestionListDom])]);
11685
+ }, [props.content.length > 1 && answerNav, showOperates && operateDom])]);
11401
11686
  };
11402
11687
  }
11403
11688
  });
11404
11689
 
11405
- const QuestionBubble = vue.defineComponent({
11406
- setup() {
11407
- return () => vue.createVNode("div", {
11408
- "class": "question-bubble chat-bubble"
11409
- }, [vue.createVNode(Avatar, {
11410
- "reverse": true,
11411
- "avatar": "",
11412
- "name": "\u5F20\u660E\u5FD7"
11413
- }, null), vue.createVNode("div", {
11414
- "class": "bubble question"
11415
- }, ["\u6562\u4E0D\u6562\u8DDF\u6211\u6BD4\u5212\u6BD4\u5212"]), vue.createVNode("div", {
11416
- "class": "operates"
11417
- }, null)]);
11690
+ const QaContext = vue.defineComponent({
11691
+ emits: ["regenerate"],
11692
+ props: {
11693
+ list: {
11694
+ type: Array,
11695
+ default: () => []
11696
+ }
11697
+ },
11698
+ setup(props, {
11699
+ emit
11700
+ }) {
11701
+ const containerRef = vue.ref();
11702
+ const onAnswerRender = text => {
11703
+ containerRef.value.scrollTo({
11704
+ top: containerRef.value.scrollHeight,
11705
+ behavior: "smooth"
11706
+ });
11707
+ };
11708
+ const handleDeleteAnswer = (questionId, answerId) => {
11709
+ const question = props.list.find(item => item.id === questionId);
11710
+ if (question) {
11711
+ question.answers = question.answers.filter(item => item.id !== answerId);
11712
+ }
11713
+ };
11714
+ return () => {
11715
+ const contextList = [];
11716
+ for (let i = 0; i < props.list.length; i++) {
11717
+ const questionItem = props.list[i];
11718
+ const prevItem = props.list[i - 1];
11719
+ const currentTime = questionItem.timestamp;
11720
+ let timeDiff = 0;
11721
+ if (prevItem) {
11722
+ const prevTime = prevItem.timestamp;
11723
+ timeDiff = currentTime - prevTime;
11724
+ }
11725
+ if (!prevItem || timeDiff > 1e3 * 60 * 5) {
11726
+ contextList.push(vue.createVNode("div", {
11727
+ "class": "time-line"
11728
+ }, [dayjs__default["default"](currentTime).format("MM/DD HH:mm")]));
11729
+ }
11730
+ if (questionItem.content) {
11731
+ contextList.push(vue.createVNode(QuestionBubble, {
11732
+ "content": questionItem.content
11733
+ }, null));
11734
+ }
11735
+ if (questionItem.answers.length > 0) {
11736
+ contextList.push(vue.createVNode(AnswerBubble, {
11737
+ "onRender": onAnswerRender,
11738
+ "content": questionItem.answers,
11739
+ "onDelete": answerId => handleDeleteAnswer(questionItem.id, answerId),
11740
+ "onRegenerate": () => emit("regenerate", questionItem.id)
11741
+ }, null));
11742
+ }
11743
+ }
11744
+ return vue.createVNode("div", {
11745
+ "class": "qa-context",
11746
+ "ref": containerRef
11747
+ }, [contextList]);
11748
+ };
11418
11749
  }
11419
11750
  });
11420
11751
 
@@ -11434,11 +11765,26 @@ const ChatBox = vue.defineComponent({
11434
11765
  emit
11435
11766
  }) {
11436
11767
  vue.provide("chat-theme", props.theme);
11437
- vue.ref();
11768
+ const {
11769
+ context,
11770
+ answerLoading,
11771
+ sendQuestion,
11772
+ abortRequest
11773
+ } = useQA();
11774
+ vue.provide("answerLoading", answerLoading);
11775
+ vue.provide("abortRequest", abortRequest);
11776
+ const handleSend = (msg, questionId) => {
11777
+ sendQuestion(msg, questionId);
11778
+ };
11438
11779
  return () => {
11439
11780
  return vue.createVNode("div", {
11440
11781
  "class": ["inl-chat-box", `inl-chat-box-${props.theme}`]
11441
- }, [vue.createVNode(AnswerBubble, null, null), vue.createVNode(QuestionBubble, null, null), vue.createVNode(Bottom, null, null)]);
11782
+ }, [vue.createVNode(QaContext, {
11783
+ "list": context.value,
11784
+ "onRegenerate": qId => handleSend("", qId)
11785
+ }, null), vue.createVNode(Bottom, {
11786
+ "onSend": handleSend
11787
+ }, null)]);
11442
11788
  };
11443
11789
  }
11444
11790
  });