@difizen/libro-prompt-cell 0.3.0 → 0.3.2

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.
Files changed (47) hide show
  1. package/es/code-block.d.ts +3 -0
  2. package/es/code-block.d.ts.map +1 -0
  3. package/es/code-block.js +110 -0
  4. package/es/index.less +69 -6
  5. package/es/input-handler/variable-name-input.d.ts +6 -6
  6. package/es/input-handler/variable-name-input.d.ts.map +1 -1
  7. package/es/interpreter-code-output-render.d.ts +6 -0
  8. package/es/interpreter-code-output-render.d.ts.map +1 -0
  9. package/es/interpreter-code-output-render.js +25 -0
  10. package/es/interpreter-code-output-rendermime-contribution.d.ts +13 -0
  11. package/es/interpreter-code-output-rendermime-contribution.d.ts.map +1 -0
  12. package/es/interpreter-code-output-rendermime-contribution.js +22 -0
  13. package/es/libro-formatter-prompt-magic-contribution.d.ts +15 -1
  14. package/es/libro-formatter-prompt-magic-contribution.d.ts.map +1 -1
  15. package/es/libro-formatter-prompt-magic-contribution.js +18 -2
  16. package/es/module.d.ts.map +1 -1
  17. package/es/module.js +2 -1
  18. package/es/prompt-cell-model.d.ts +14 -18
  19. package/es/prompt-cell-model.d.ts.map +1 -1
  20. package/es/prompt-cell-model.js +66 -27
  21. package/es/prompt-cell-protocol.d.ts +7 -0
  22. package/es/prompt-cell-protocol.d.ts.map +1 -1
  23. package/es/prompt-cell-script.d.ts +1 -0
  24. package/es/prompt-cell-script.d.ts.map +1 -1
  25. package/es/prompt-cell-script.js +3 -0
  26. package/es/prompt-cell-view.d.ts +16 -9
  27. package/es/prompt-cell-view.d.ts.map +1 -1
  28. package/es/prompt-cell-view.js +329 -62
  29. package/es/prompt-output-render.d.ts.map +1 -1
  30. package/es/prompt-output-render.js +17 -3
  31. package/package.json +11 -6
  32. package/src/code-block.tsx +107 -0
  33. package/src/index.less +69 -6
  34. package/src/input-handler/variable-name-input.tsx +6 -6
  35. package/src/interpreter-code-output-render.tsx +28 -0
  36. package/src/interpreter-code-output-rendermime-contribution.ts +18 -0
  37. package/src/libro-formatter-prompt-magic-contribution.ts +21 -0
  38. package/src/module.ts +2 -0
  39. package/src/prompt-cell-model.ts +42 -11
  40. package/src/prompt-cell-protocol.ts +8 -0
  41. package/src/prompt-cell-script.ts +3 -0
  42. package/src/prompt-cell-view.tsx +251 -14
  43. package/src/prompt-output-render.tsx +22 -8
  44. package/es/libro-llm-render.d.ts +0 -10
  45. package/es/libro-llm-render.d.ts.map +0 -1
  46. package/es/libro-llm-render.js +0 -75
  47. package/src/libro-llm-render.tsx +0 -64
@@ -1,15 +1,23 @@
1
+ import { EditOutlined } from '@ant-design/icons';
1
2
  import type { IRange } from '@difizen/libro-code-editor';
2
3
  import type { ICodeCell, IOutput } from '@difizen/libro-common';
4
+ import { MIME } from '@difizen/libro-common';
3
5
  import { isOutput } from '@difizen/libro-common';
4
6
  import type {
7
+ ExecutionMeta,
8
+ KernelMessage,
5
9
  IOutputAreaOption,
6
10
  LibroCell,
7
11
  CellViewOptions,
8
- } from '@difizen/libro-core';
9
- import { LibroOutputArea } from '@difizen/libro-core';
10
- import { CellService, LibroEditableExecutableCellView } from '@difizen/libro-core';
11
- import type { ExecutionMeta, KernelMessage } from '@difizen/libro-jupyter';
12
- import { KernelError, LibroJupyterModel } from '@difizen/libro-jupyter';
12
+ } from '@difizen/libro-jupyter';
13
+ import {
14
+ KernelError,
15
+ LibroJupyterModel,
16
+ CellService,
17
+ LibroEditableExecutableCellView,
18
+ LibroOutputArea,
19
+ } from '@difizen/libro-jupyter';
20
+ import { ChatComponents } from '@difizen/magent-chat';
13
21
  import {
14
22
  getOrigin,
15
23
  inject,
@@ -22,13 +30,17 @@ import {
22
30
  ViewOption,
23
31
  ViewRender,
24
32
  watch,
33
+ Deferred,
25
34
  } from '@difizen/mana-app';
26
- import { Deferred } from '@difizen/mana-app';
27
35
  import { l10n } from '@difizen/mana-l10n';
28
36
  import { Select, Tag } from 'antd';
37
+ import type { DefaultOptionType } from 'antd/es/select/index.js';
29
38
  import classNames from 'classnames';
30
39
  import React, { useEffect, useState } from 'react';
40
+ import breaks from 'remark-breaks';
41
+ import remarkGfm from 'remark-gfm';
31
42
 
43
+ import { CodeBlock } from './code-block.js';
32
44
  import { ChatRecordInput, VariableNameInput } from './input-handler/index.js';
33
45
  import { LibroPromptCellModel } from './prompt-cell-model.js';
34
46
  import { PromptScript } from './prompt-cell-script.js';
@@ -40,6 +52,9 @@ export interface ChatObject {
40
52
  order: number;
41
53
  key: string;
42
54
  disabled?: boolean;
55
+ support_interpreter?: 'dynamic' | 'immutable' | 'disable';
56
+ interpreter_enabled?: boolean;
57
+ [key: string]: any;
43
58
  }
44
59
 
45
60
  function ChatObjectFromKey(key: string): ChatObject {
@@ -92,6 +107,42 @@ const ChatObjectOptions = (type: string): ChatObjectOptions => {
92
107
  }
93
108
  };
94
109
 
110
+ const InterpreterMode = () => {
111
+ const instance = useInject<LibroPromptCellView>(ViewInstance);
112
+ // const handleInterpreterSwitch = (checked: boolean) => {
113
+ // instance.model.interpreterEnabled = checked;
114
+ // if (instance.model.chatKey) {
115
+ // instance.switchInterpreterMode(instance.model.chatKey, checked);
116
+ // instance.model.promptOutput = undefined;
117
+ // instance.model.interpreterCode = undefined;
118
+ // }
119
+ // };
120
+
121
+ if (instance.model.supportInterpreter === 'immutable') {
122
+ return (
123
+ <Tag bordered={false} color="geekblue">
124
+ Interpreter
125
+ </Tag>
126
+ );
127
+ }
128
+
129
+ // if (instance.model.supportInterpreter === 'dynamic') {
130
+ // return (
131
+ // <div>
132
+ // <span className="libro-prompt-cell-interpreter-switch-tip">
133
+ // {instance.model.interpreterEnabled ? '关闭 Interpreter' : '开启 Interpreter'}
134
+ // </span>
135
+ // <Switch
136
+ // size="small"
137
+ // className="libro-prompt-cell-interpreter-switch"
138
+ // onChange={handleInterpreterSwitch}
139
+ // />
140
+ // </div>
141
+ // );
142
+ // }
143
+ return null;
144
+ };
145
+
95
146
  const SelectionItemLabel: React.FC<{ item: ChatObject }> = (props: {
96
147
  item: ChatObject;
97
148
  }) => {
@@ -126,8 +177,9 @@ const CellEditorRaw: React.FC = () => {
126
177
  export const CellEditor = React.memo(CellEditorRaw);
127
178
 
128
179
  const PropmtEditorViewComponent = React.forwardRef<HTMLDivElement>(
129
- function MaxPropmtEditorViewComponent(props, ref) {
180
+ function PropmtEditorViewComponent(props, ref) {
130
181
  const instance = useInject<LibroPromptCellView>(ViewInstance);
182
+ const LLMRender = ChatComponents.Markdown;
131
183
  const [selectedModel, setSelectedModel] = useState<string>(l10n.t('暂无内置模型'));
132
184
  useEffect(() => {
133
185
  // TODO: Data initialization should not depend on view initialization, which causes limitations in usage scenarios and multiple renderings.
@@ -154,11 +206,25 @@ const PropmtEditorViewComponent = React.forwardRef<HTMLDivElement>(
154
206
  // eslint-disable-next-line react-hooks/exhaustive-deps
155
207
  }, []);
156
208
 
157
- const handleChange = (value: string) => {
158
- instance.handleModelNameChange(value);
209
+ const handleChange = (value: string, options?: DefaultOptionType) => {
210
+ instance.handleModelNameChange(value, options);
159
211
  setSelectedModel(value);
160
212
  };
161
213
 
214
+ const replace = (data: string) => {
215
+ if (instance instanceof LibroPromptCellView && instance.editor) {
216
+ const length = instance.editor.model.value.length;
217
+ const start = instance.editor.getPositionAt(0);
218
+ const end = instance.editor.getPositionAt(length);
219
+ if (start && end) {
220
+ instance.editor.replaceSelection(data, {
221
+ start,
222
+ end,
223
+ });
224
+ }
225
+ }
226
+ };
227
+
162
228
  return (
163
229
  <div
164
230
  className={instance.className}
@@ -180,13 +246,16 @@ const PropmtEditorViewComponent = React.forwardRef<HTMLDivElement>(
180
246
  }}
181
247
  />
182
248
  </span>
249
+ <div className="libro-prompt-cell-interpreter-header-container">
250
+ <InterpreterMode />
251
+ </div>
183
252
  <VariableNameInput
184
253
  value={instance.model.variableName}
185
254
  checkVariableNameAvailable={instance.checkVariableNameAvailable}
186
255
  handleVariableNameChange={instance.handleVariableNameChange}
187
256
  />
188
257
  </div>
189
- <div>
258
+ <div className="libro-prompt-cell-right-header">
190
259
  <ChatRecordInput
191
260
  value={instance.model.record}
192
261
  handleChange={instance.handleRecordChange}
@@ -195,7 +264,39 @@ const PropmtEditorViewComponent = React.forwardRef<HTMLDivElement>(
195
264
  />
196
265
  </div>
197
266
  </div>
198
- <CellEditor />
267
+ {instance.interpreterEditMode && (
268
+ <>
269
+ <div className="libro-prompt-cell-model-prompt">
270
+ {instance.model.prompt}
271
+ </div>
272
+ <div className="libro-prompt-cell-model-tip">
273
+ <LLMRender
274
+ type="message"
275
+ remarkPlugins={[remarkGfm, breaks]}
276
+ components={{ code: CodeBlock }}
277
+ >
278
+ {instance.model.promptOutput}
279
+ </LLMRender>
280
+ </div>
281
+ </>
282
+ )}
283
+ <div className="libro-edit-container">
284
+ {instance.interpreterEditMode && (
285
+ <div
286
+ className="libro-interpreter-edit-container"
287
+ onClick={() => {
288
+ instance.interpreterEditMode = false;
289
+ if (instance.model.prompt) {
290
+ replace(instance.model.prompt);
291
+ }
292
+ }}
293
+ >
294
+ <div className="libro-interpreter-edit-tip">退出编辑</div>
295
+ <EditOutlined className="libro-interpreter-edit-icon" />
296
+ </div>
297
+ )}
298
+ <CellEditor />
299
+ </div>
199
300
  </div>
200
301
  );
201
302
  },
@@ -215,6 +316,50 @@ export class LibroPromptCellView extends LibroEditableExecutableCellView {
215
316
  @prop()
216
317
  contextChatRecords: string[] = [];
217
318
 
319
+ get interpreterEditMode() {
320
+ return this.model._interpreterEditMode;
321
+ }
322
+
323
+ set interpreterEditMode(data) {
324
+ this.model._interpreterEditMode = data;
325
+ if (data) {
326
+ this.model.prompt = this.model.value;
327
+ this.model.mimeType = MIME.python;
328
+ this.outputArea.clear();
329
+ this.parent.enterEditMode();
330
+ this.parent.model.savable = false;
331
+ this.parent.model.runnable = false;
332
+ } else {
333
+ this.parent.model.savable = true;
334
+ this.model.interpreterCode = this.model.value;
335
+ this.model.mimeType = 'application/vnd.libro.prompt+json';
336
+ this.parent.model.runnable = true;
337
+ this.handleInterpreterOutput();
338
+ }
339
+ }
340
+
341
+ handleInterpreterOutput = async () => {
342
+ if (this.model.promptOutput) {
343
+ await this.outputArea.add({
344
+ data: {
345
+ 'application/vnd.libro.prompt+json': this.model.promptOutput,
346
+ },
347
+ metadata: {},
348
+ output_type: 'display_data',
349
+ });
350
+ }
351
+ if (this.model.interpreterCode) {
352
+ await this.outputArea.add({
353
+ data: {
354
+ 'application/vnd.libro.interpreter.code+text': this.model.interpreterCode,
355
+ },
356
+ metadata: {},
357
+ output_type: 'display_data',
358
+ });
359
+ this.runInterpreterCode();
360
+ }
361
+ };
362
+
218
363
  get sortedChatObjects(): ChatObject[] {
219
364
  const map = new Map<string, ChatObject>();
220
365
  this.parent.model.cells.forEach((cell) => {
@@ -441,6 +586,81 @@ export class LibroPromptCellView extends LibroEditableExecutableCellView {
441
586
  }
442
587
  }
443
588
 
589
+ async runInterpreterCode() {
590
+ const libroModel = this.parent.model;
591
+
592
+ if (
593
+ !libroModel ||
594
+ !(libroModel instanceof LibroJupyterModel) ||
595
+ !libroModel.kernelConnection ||
596
+ libroModel.kernelConnection.isDisposed
597
+ ) {
598
+ return false;
599
+ }
600
+
601
+ const kernelConnection = getOrigin(libroModel.kernelConnection);
602
+ const cellModel = this.model;
603
+
604
+ if (!cellModel.interpreterCode) {
605
+ return false;
606
+ }
607
+
608
+ try {
609
+ cellModel.executing = true;
610
+ const future = kernelConnection.requestExecute({
611
+ code: cellModel.interpreterCode,
612
+ });
613
+
614
+ let startTimeStr = '';
615
+ future.onIOPub = (msg: any) => {
616
+ if (msg.header.msg_type === 'execute_input') {
617
+ cellModel.metadata.execution = {
618
+ 'shell.execute_reply.started': '',
619
+ 'shell.execute_reply.end': '',
620
+ to_execute: new Date().toISOString(),
621
+ } as ExecutionMeta;
622
+ cellModel.kernelExecuting = true;
623
+ startTimeStr = msg.header.date as string;
624
+ const meta = cellModel.metadata.execution as ExecutionMeta;
625
+ if (meta) {
626
+ meta['shell.execute_reply.started'] = startTimeStr;
627
+ }
628
+ }
629
+ cellModel.msgChangeEmitter.fire(msg);
630
+ };
631
+ future.onReply = (msg: any) => {
632
+ cellModel.msgChangeEmitter.fire(msg);
633
+ };
634
+
635
+ const msgPromise = await future.done;
636
+ cellModel.executing = false;
637
+ cellModel.kernelExecuting = false;
638
+
639
+ startTimeStr = msgPromise.metadata['started'] as string;
640
+ const endTimeStr = msgPromise.header.date;
641
+
642
+ (cellModel.metadata.execution as ExecutionMeta)['shell.execute_reply.started'] =
643
+ startTimeStr;
644
+ (cellModel.metadata.execution as ExecutionMeta)['shell.execute_reply.end'] =
645
+ endTimeStr;
646
+
647
+ if (!msgPromise) {
648
+ return true;
649
+ }
650
+
651
+ if (msgPromise.content.status === 'ok') {
652
+ return true;
653
+ } else {
654
+ throw new KernelError(msgPromise.content);
655
+ }
656
+ } catch (reason: any) {
657
+ if (reason.message.startsWith('Canceled')) {
658
+ return false;
659
+ }
660
+ throw reason;
661
+ }
662
+ }
663
+
444
664
  fetch = async (
445
665
  content: KernelMessage.IExecuteRequestMsg['content'],
446
666
  ioCallback: (msg: KernelMessage.IIOPubMessage) => any,
@@ -475,6 +695,19 @@ export class LibroPromptCellView extends LibroEditableExecutableCellView {
475
695
  }),
476
696
  );
477
697
  };
698
+
699
+ switchInterpreterMode = async (chatKey: string, mode: boolean) => {
700
+ return this.fetch(
701
+ {
702
+ code: this.promptScript.switchInterpreterMode(chatKey, mode),
703
+ store_history: false,
704
+ },
705
+ (msg) => {
706
+ //
707
+ },
708
+ );
709
+ };
710
+
478
711
  updateChatRecords = async () => {
479
712
  return this.fetch(
480
713
  {
@@ -497,6 +730,7 @@ export class LibroPromptCellView extends LibroEditableExecutableCellView {
497
730
  value: item.key,
498
731
  label: <SelectionItemLabel item={item} />,
499
732
  disabled: !!item.disabled,
733
+ support_interpreter: item.support_interpreter,
500
734
  };
501
735
  };
502
736
 
@@ -533,7 +767,7 @@ export class LibroPromptCellView extends LibroEditableExecutableCellView {
533
767
  }
534
768
  };
535
769
 
536
- checkVariableNameAvailable = (variableName: string) => {
770
+ checkVariableNameAvailable = (variableName?: string) => {
537
771
  return (
538
772
  this.parent.model.cells.findIndex(
539
773
  (cell) =>
@@ -542,10 +776,13 @@ export class LibroPromptCellView extends LibroEditableExecutableCellView {
542
776
  ) > -1
543
777
  );
544
778
  };
545
- handleModelNameChange = (value: string) => {
779
+ handleModelNameChange = (value: string, option?: DefaultOptionType) => {
546
780
  this.model.chatKey = value;
781
+ if (option) {
782
+ this.model.supportInterpreter = option['support_interpreter'];
783
+ }
547
784
  };
548
- handleVariableNameChange = (value: string) => {
785
+ handleVariableNameChange = (value?: string) => {
549
786
  this.model.variableName = value;
550
787
  };
551
788
  handleRecordChange = (value: string | undefined) => {
@@ -1,19 +1,19 @@
1
- import type {
2
- IMimeBundle,
3
- MultilineString,
4
- PartialJSONObject,
5
- } from '@difizen/libro-common';
1
+ import type { MultilineString, PartialJSONObject } from '@difizen/libro-common';
6
2
  import { copy2clipboard } from '@difizen/libro-common';
7
3
  import { concatMultilineString } from '@difizen/libro-common';
8
4
  import type { BaseOutputView } from '@difizen/libro-jupyter';
9
5
  import { NotebookCommands } from '@difizen/libro-jupyter';
6
+ import { ChatComponents } from '@difizen/magent-chat';
10
7
  import { CommandRegistry, useInject } from '@difizen/mana-app';
11
8
  import { l10n } from '@difizen/mana-l10n';
12
9
  import React, { useState } from 'react';
10
+ import breaks from 'remark-breaks';
11
+ import remarkGfm from 'remark-gfm';
13
12
  import { v4 } from 'uuid';
14
13
 
15
- import { LibroLLMRenderMemo } from './libro-llm-render.js';
14
+ import { CodeBlock } from './code-block.js';
16
15
  import { getPythonCode } from './prompt-cell-utils.js';
16
+ import { LibroPromptCellView } from './prompt-cell-view.js';
17
17
 
18
18
  const getModelOutput = (data: PartialJSONObject | MultilineString) => {
19
19
  if (typeof data === 'string' || Array.isArray(data)) {
@@ -29,18 +29,26 @@ export const PromptOutputRender: React.FC<{
29
29
  const { model } = props;
30
30
  const renderHTMLRef = React.createRef<HTMLDivElement>();
31
31
  const commandRegistry = useInject(CommandRegistry);
32
+ const LLMRender = ChatComponents.Markdown;
32
33
  const [selection, setSelection] = useState('');
33
34
 
34
35
  if (!model.data['application/vnd.libro.prompt+json']) {
35
36
  return null;
36
37
  }
37
38
 
38
- const data = model.data['application/vnd.libro.prompt+json'] as IMimeBundle;
39
+ if (!(model.cell instanceof LibroPromptCellView)) {
40
+ return null;
41
+ }
42
+ const data = model.data['application/vnd.libro.prompt+json'] as
43
+ | PartialJSONObject
44
+ | MultilineString;
39
45
 
40
46
  if (!data) {
41
47
  return null;
42
48
  }
49
+
43
50
  const modelData = getModelOutput(data);
51
+ model.cell.model.promptOutput = modelData;
44
52
  const sourceArr = getPythonCode(modelData ?? '');
45
53
  const insertAndRun = async () => {
46
54
  const libro = model.cell.parent;
@@ -98,7 +106,13 @@ export const PromptOutputRender: React.FC<{
98
106
  <div className="libro-prompt-output-render-container" onMouseUp={updateSelection}>
99
107
  <div className="prompt-output-render" ref={renderHTMLRef}>
100
108
  <div className="libro-prompt-output-llm-render">
101
- <LibroLLMRenderMemo data={modelData} />
109
+ <LLMRender
110
+ type="message"
111
+ components={{ code: CodeBlock }}
112
+ remarkPlugins={[remarkGfm, breaks]}
113
+ >
114
+ {modelData}
115
+ </LLMRender>
102
116
  </div>
103
117
  </div>
104
118
  {sourceArr.length > 0 && (
@@ -1,10 +0,0 @@
1
- import React from 'react';
2
- import 'highlight.js/styles/default.css';
3
- import './index.less';
4
- export declare const LibroLLMRender: React.FC<{
5
- data: string;
6
- }>;
7
- export declare const LibroLLMRenderMemo: React.NamedExoticComponent<{
8
- data: string;
9
- }>;
10
- //# sourceMappingURL=libro-llm-render.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"libro-llm-render.d.ts","sourceRoot":"","sources":["../src/libro-llm-render.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAqD,MAAM,OAAO,CAAC;AAC1E,OAAO,iCAAiC,CAAC;AAEzC,OAAO,cAAc,CAAC;AAiBtB,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAqCrD,CAAC;AACF,eAAO,MAAM,kBAAkB;UAtCe,MAAM;EAsCE,CAAC"}
@@ -1,75 +0,0 @@
1
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
2
- function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
4
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
5
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
6
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
7
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
8
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
9
- function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
10
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
11
- import { ToolbarRender } from '@difizen/mana-app';
12
- import hljs from 'highlight.js';
13
- import { marked } from 'marked';
14
- import { markedHighlight } from 'marked-highlight';
15
- import markedKatex from 'marked-katex-extension';
16
- import React, { useEffect, useRef, memo, useState, useMemo } from 'react';
17
- import 'highlight.js/styles/default.css';
18
- import { createPortal } from 'react-dom';
19
- import "./index.less";
20
- import { jsx as _jsx } from "react/jsx-runtime";
21
- marked.use(markedKatex({
22
- throwOnError: false,
23
- output: 'mathml'
24
- }), markedHighlight({
25
- langPrefix: 'libro-llm-hljs code-block language-',
26
- highlight: function highlight(code, lang) {
27
- var language = hljs.getLanguage(lang) ? lang : 'python';
28
- return hljs.highlight(code, {
29
- language: language
30
- }).value;
31
- }
32
- }), {
33
- headerIds: false,
34
- mangle: false
35
- });
36
- export var LibroLLMRender = function LibroLLMRender(props) {
37
- var data = props.data;
38
- var renderMarkdownRef = useRef(null);
39
- // const LLMExtraRender = useInject<LLMExtraRenderProvider>(LLMExtraRenderProvider);
40
- var _useState = useState([]),
41
- _useState2 = _slicedToArray(_useState, 2),
42
- renderExtraList = _useState2[0],
43
- setRenderExtraList = _useState2[1];
44
- var codeToolbarArgs = useMemo(function () {
45
- return [data, 'CodeToolbar'];
46
- }, [data]);
47
- useEffect(function () {
48
- if (!renderMarkdownRef.current) {
49
- return;
50
- }
51
- renderMarkdownRef.current.innerHTML = marked.parse(data);
52
- var hljsElements = renderMarkdownRef.current.getElementsByClassName('libro-llm-hljs');
53
- for (var i = 0; i < hljsElements.length; i++) {
54
- var newElement = document.createElement('div');
55
- var newRenderExtraList = [].concat(_toConsumableArray(renderExtraList), [newElement]);
56
- setRenderExtraList(newRenderExtraList);
57
- var hljsElement = hljsElements.item(i);
58
- if (hljsElement) {
59
- var _hljsElement$parentNo;
60
- (_hljsElement$parentNo = hljsElement.parentNode) === null || _hljsElement$parentNo === void 0 || _hljsElement$parentNo.insertBefore(newElement, hljsElement.nextSibling);
61
- }
62
- }
63
- }, [data]); // eslint-disable-line react-hooks/exhaustive-deps
64
-
65
- return /*#__PURE__*/_jsx("div", {
66
- className: "libro-llm-output-render",
67
- ref: renderMarkdownRef,
68
- children: renderExtraList.map(function (element) {
69
- return /*#__PURE__*/createPortal( /*#__PURE__*/_jsx(ToolbarRender, {
70
- data: codeToolbarArgs
71
- }), element);
72
- })
73
- });
74
- };
75
- export var LibroLLMRenderMemo = /*#__PURE__*/memo(LibroLLMRender);
@@ -1,64 +0,0 @@
1
- import { ToolbarRender } from '@difizen/mana-app';
2
- import hljs from 'highlight.js';
3
- import { marked } from 'marked';
4
- import { markedHighlight } from 'marked-highlight';
5
- import markedKatex from 'marked-katex-extension';
6
- import React, { useEffect, useRef, memo, useState, useMemo } from 'react';
7
- import 'highlight.js/styles/default.css';
8
- import { createPortal } from 'react-dom';
9
- import './index.less';
10
-
11
- marked.use(
12
- markedKatex({
13
- throwOnError: false,
14
- output: 'mathml',
15
- }),
16
- markedHighlight({
17
- langPrefix: 'libro-llm-hljs code-block language-',
18
- highlight(code: string, lang: string) {
19
- const language = hljs.getLanguage(lang) ? lang : 'python';
20
- return hljs.highlight(code, { language }).value;
21
- },
22
- }),
23
- { headerIds: false, mangle: false },
24
- );
25
-
26
- export const LibroLLMRender: React.FC<{ data: string }> = (props: { data: string }) => {
27
- const { data } = props;
28
-
29
- const renderMarkdownRef = useRef<HTMLDivElement>(null);
30
- // const LLMExtraRender = useInject<LLMExtraRenderProvider>(LLMExtraRenderProvider);
31
- const [renderExtraList, setRenderExtraList] = useState<HTMLDivElement[]>([]);
32
- const codeToolbarArgs = useMemo(() => {
33
- return [data, 'CodeToolbar'];
34
- }, [data]);
35
-
36
- useEffect(() => {
37
- if (!renderMarkdownRef.current) {
38
- return;
39
- }
40
- renderMarkdownRef.current.innerHTML = marked.parse(data);
41
-
42
- const hljsElements =
43
- renderMarkdownRef.current.getElementsByClassName('libro-llm-hljs');
44
-
45
- for (let i = 0; i < hljsElements.length; i++) {
46
- const newElement = document.createElement('div');
47
- const newRenderExtraList = [...renderExtraList, newElement];
48
- setRenderExtraList(newRenderExtraList);
49
- const hljsElement = hljsElements.item(i);
50
- if (hljsElement) {
51
- hljsElement.parentNode?.insertBefore(newElement, hljsElement.nextSibling);
52
- }
53
- }
54
- }, [data]); // eslint-disable-line react-hooks/exhaustive-deps
55
-
56
- return (
57
- <div className="libro-llm-output-render" ref={renderMarkdownRef}>
58
- {renderExtraList.map((element) => {
59
- return createPortal(<ToolbarRender data={codeToolbarArgs} />, element);
60
- })}
61
- </div>
62
- );
63
- };
64
- export const LibroLLMRenderMemo = memo(LibroLLMRender);