@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.
- package/es/code-block.d.ts +3 -0
- package/es/code-block.d.ts.map +1 -0
- package/es/code-block.js +110 -0
- package/es/index.less +69 -6
- package/es/input-handler/variable-name-input.d.ts +6 -6
- package/es/input-handler/variable-name-input.d.ts.map +1 -1
- package/es/interpreter-code-output-render.d.ts +6 -0
- package/es/interpreter-code-output-render.d.ts.map +1 -0
- package/es/interpreter-code-output-render.js +25 -0
- package/es/interpreter-code-output-rendermime-contribution.d.ts +13 -0
- package/es/interpreter-code-output-rendermime-contribution.d.ts.map +1 -0
- package/es/interpreter-code-output-rendermime-contribution.js +22 -0
- package/es/libro-formatter-prompt-magic-contribution.d.ts +15 -1
- package/es/libro-formatter-prompt-magic-contribution.d.ts.map +1 -1
- package/es/libro-formatter-prompt-magic-contribution.js +18 -2
- package/es/module.d.ts.map +1 -1
- package/es/module.js +2 -1
- package/es/prompt-cell-model.d.ts +14 -18
- package/es/prompt-cell-model.d.ts.map +1 -1
- package/es/prompt-cell-model.js +66 -27
- package/es/prompt-cell-protocol.d.ts +7 -0
- package/es/prompt-cell-protocol.d.ts.map +1 -1
- package/es/prompt-cell-script.d.ts +1 -0
- package/es/prompt-cell-script.d.ts.map +1 -1
- package/es/prompt-cell-script.js +3 -0
- package/es/prompt-cell-view.d.ts +16 -9
- package/es/prompt-cell-view.d.ts.map +1 -1
- package/es/prompt-cell-view.js +329 -62
- package/es/prompt-output-render.d.ts.map +1 -1
- package/es/prompt-output-render.js +17 -3
- package/package.json +11 -6
- package/src/code-block.tsx +107 -0
- package/src/index.less +69 -6
- package/src/input-handler/variable-name-input.tsx +6 -6
- package/src/interpreter-code-output-render.tsx +28 -0
- package/src/interpreter-code-output-rendermime-contribution.ts +18 -0
- package/src/libro-formatter-prompt-magic-contribution.ts +21 -0
- package/src/module.ts +2 -0
- package/src/prompt-cell-model.ts +42 -11
- package/src/prompt-cell-protocol.ts +8 -0
- package/src/prompt-cell-script.ts +3 -0
- package/src/prompt-cell-view.tsx +251 -14
- package/src/prompt-output-render.tsx +22 -8
- package/es/libro-llm-render.d.ts +0 -10
- package/es/libro-llm-render.d.ts.map +0 -1
- package/es/libro-llm-render.js +0 -75
- package/src/libro-llm-render.tsx +0 -64
package/src/prompt-cell-view.tsx
CHANGED
|
@@ -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-
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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 {
|
|
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
|
-
|
|
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
|
-
<
|
|
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 && (
|
package/es/libro-llm-render.d.ts
DELETED
|
@@ -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"}
|
package/es/libro-llm-render.js
DELETED
|
@@ -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);
|
package/src/libro-llm-render.tsx
DELETED
|
@@ -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);
|