@datalayer/agent-runtimes 0.0.12 → 1.0.0
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/lib/AgentLexical.d.ts +0 -1
- package/lib/AgentLexical.js +0 -1
- package/lib/examples/AgentRuntimeLexical2Example.d.ts +0 -1
- package/lib/examples/AgentRuntimeLexical2Example.js +0 -1
- package/lib/examples/AgentRuntimeLexicalExample.d.ts +0 -1
- package/lib/examples/AgentRuntimeLexicalExample.js +0 -1
- package/lib/examples/AgentRuntimeLexicalSidebarExample.d.ts +0 -1
- package/lib/examples/AgentRuntimeLexicalSidebarExample.js +0 -1
- package/lib/examples/CopilotKitLexicalExample.d.ts +0 -1
- package/lib/examples/CopilotKitLexicalExample.js +0 -1
- package/lib/lexical/ChatInlinePlugin.js +28 -7
- package/lib/lexical/index.d.ts +1 -1
- package/lib/lexical/useChatInlineToolbarItems.d.ts +9 -2
- package/lib/lexical/useChatInlineToolbarItems.js +22 -94
- package/package.json +1 -1
package/lib/AgentLexical.d.ts
CHANGED
|
@@ -28,7 +28,6 @@ import 'prismjs/components/prism-swift';
|
|
|
28
28
|
import React from 'react';
|
|
29
29
|
import '@datalayer/jupyter-lexical/style/index.css';
|
|
30
30
|
import './examples/lexical/lexical-theme.css';
|
|
31
|
-
import '@datalayer/jupyter-lexical/style/modal-overrides.css';
|
|
32
31
|
import '../style/primer-primitives.css';
|
|
33
32
|
export declare const AgentLexical: React.FC;
|
|
34
33
|
export default AgentLexical;
|
package/lib/AgentLexical.js
CHANGED
|
@@ -61,7 +61,6 @@ import { editorConfig } from './examples/lexical/editorConfig';
|
|
|
61
61
|
import { DEFAULT_MODEL } from './specs';
|
|
62
62
|
import '@datalayer/jupyter-lexical/style/index.css';
|
|
63
63
|
import './examples/lexical/lexical-theme.css';
|
|
64
|
-
import '@datalayer/jupyter-lexical/style/modal-overrides.css';
|
|
65
64
|
import '../style/primer-primitives.css';
|
|
66
65
|
setupPrimerPortals();
|
|
67
66
|
const BASE_URL = window.location.origin;
|
|
@@ -27,7 +27,6 @@ import 'prismjs/components/prism-rust';
|
|
|
27
27
|
import 'prismjs/components/prism-swift';
|
|
28
28
|
import type { ServiceManager } from '@jupyterlab/services';
|
|
29
29
|
import '@datalayer/jupyter-lexical/style/index.css';
|
|
30
|
-
import '@datalayer/jupyter-lexical/style/modal-overrides.css';
|
|
31
30
|
import './lexical/lexical-theme.css';
|
|
32
31
|
/**
|
|
33
32
|
* Chat Lexical Example with Simple integration
|
|
@@ -54,7 +54,6 @@ import { ChatFloating, useChatStore, useFrontendTool, DatalayerInferenceProvider
|
|
|
54
54
|
import { useLexicalToolActions, ActionRegistrar, } from '../tools/adapters/copilotkit/lexicalHooks';
|
|
55
55
|
import { editorConfig } from './lexical/editorConfig';
|
|
56
56
|
import '@datalayer/jupyter-lexical/style/index.css';
|
|
57
|
-
import '@datalayer/jupyter-lexical/style/modal-overrides.css';
|
|
58
57
|
import './lexical/lexical-theme.css';
|
|
59
58
|
// Fixed lexical document ID
|
|
60
59
|
const LEXICAL_ID = 'chat-popup-lexical-example';
|
|
@@ -25,7 +25,6 @@ import 'prismjs/components/prism-swift';
|
|
|
25
25
|
import type { ServiceManager } from '@jupyterlab/services';
|
|
26
26
|
import '@datalayer/jupyter-lexical/style/index.css';
|
|
27
27
|
import './lexical/lexical-theme.css';
|
|
28
|
-
import '@datalayer/jupyter-lexical/style/modal-overrides.css';
|
|
29
28
|
/**
|
|
30
29
|
* Main Agent Runtime lexical example component
|
|
31
30
|
*/
|
|
@@ -54,7 +54,6 @@ import { useLexicalTools } from '../tools/adapters/agent-runtimes/lexicalHooks';
|
|
|
54
54
|
import { editorConfig } from './lexical/editorConfig';
|
|
55
55
|
import '@datalayer/jupyter-lexical/style/index.css';
|
|
56
56
|
import './lexical/lexical-theme.css';
|
|
57
|
-
import '@datalayer/jupyter-lexical/style/modal-overrides.css';
|
|
58
57
|
// Fixed lexical document ID
|
|
59
58
|
const LEXICAL_ID = 'agui-lexical-example';
|
|
60
59
|
// Base URL for agent-runtimes server
|
|
@@ -26,7 +26,6 @@ import 'prismjs/components/prism-rust';
|
|
|
26
26
|
import 'prismjs/components/prism-swift';
|
|
27
27
|
import type { ServiceManager } from '@jupyterlab/services';
|
|
28
28
|
import '@datalayer/jupyter-lexical/style/index.css';
|
|
29
|
-
import '@datalayer/jupyter-lexical/style/modal-overrides.css';
|
|
30
29
|
import './lexical/lexical-theme.css';
|
|
31
30
|
/**
|
|
32
31
|
* Agent Runtime Lexical Sidebar Example with Simple integration
|
|
@@ -54,7 +54,6 @@ import { useChatInlineToolbarItems } from '../lexical/useChatInlineToolbarItems'
|
|
|
54
54
|
import { useLexicalTools } from '../tools/adapters/agent-runtimes/lexicalHooks';
|
|
55
55
|
import { editorConfig } from './lexical/editorConfig';
|
|
56
56
|
import '@datalayer/jupyter-lexical/style/index.css';
|
|
57
|
-
import '@datalayer/jupyter-lexical/style/modal-overrides.css';
|
|
58
57
|
import './lexical/lexical-theme.css';
|
|
59
58
|
// Fixed lexical document ID
|
|
60
59
|
const LEXICAL_ID = 'chat-lexical-example';
|
|
@@ -26,7 +26,6 @@ import 'prismjs/components/prism-swift';
|
|
|
26
26
|
import type { ServiceManager } from '@jupyterlab/services';
|
|
27
27
|
import '@datalayer/jupyter-lexical/style/index.css';
|
|
28
28
|
import '@copilotkit/react-ui/styles.css';
|
|
29
|
-
import '@datalayer/jupyter-lexical/style/modal-overrides.css';
|
|
30
29
|
import './lexical/lexical-theme.css';
|
|
31
30
|
/**
|
|
32
31
|
* Main CopilotKit lexical example component
|
|
@@ -53,7 +53,6 @@ import { ActionRegistrar, useLexicalToolActions, } from '../tools/adapters/copil
|
|
|
53
53
|
import { editorConfig } from './lexical/editorConfig';
|
|
54
54
|
import '@datalayer/jupyter-lexical/style/index.css';
|
|
55
55
|
import '@copilotkit/react-ui/styles.css';
|
|
56
|
-
import '@datalayer/jupyter-lexical/style/modal-overrides.css';
|
|
57
56
|
import './lexical/lexical-theme.css';
|
|
58
57
|
// Fixed lexical document ID
|
|
59
58
|
const LEXICAL_ID = 'agui-lexical-example';
|
|
@@ -35,7 +35,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
35
35
|
*
|
|
36
36
|
* @module lexical/ChatInlinePlugin
|
|
37
37
|
*/
|
|
38
|
-
import { useCallback, useEffect, useLayoutEffect, useRef, useState, } from 'react';
|
|
38
|
+
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, } from 'react';
|
|
39
39
|
import { createPortal } from 'react-dom';
|
|
40
40
|
import { $getSelection, $isRangeSelection, $createParagraphNode, $createTextNode, TextNode, COMMAND_PRIORITY_LOW, createCommand, } from 'lexical';
|
|
41
41
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
@@ -179,12 +179,33 @@ export function ChatInlinePlugin({ protocol, isOpen, onClose, pendingPrompt, onP
|
|
|
179
179
|
// Selection tracking
|
|
180
180
|
const { range } = useRange();
|
|
181
181
|
const selectedText = useSelectionText();
|
|
182
|
-
//
|
|
182
|
+
// ---------------------------------------------------------------
|
|
183
|
+
// Latch: save position & text when AI panel opens so that a
|
|
184
|
+
// transient selection loss (e.g. portal render triggering
|
|
185
|
+
// selectionchange) does not unmount the panel.
|
|
186
|
+
// ---------------------------------------------------------------
|
|
187
|
+
const savedRectRef = useRef(null);
|
|
188
|
+
const savedTextRef = useRef('');
|
|
189
|
+
useEffect(() => {
|
|
190
|
+
if (isOpen && range) {
|
|
191
|
+
// Keep saving the latest rect/text while open and range is valid
|
|
192
|
+
savedRectRef.current = range.getBoundingClientRect();
|
|
193
|
+
savedTextRef.current = selectedText || '';
|
|
194
|
+
}
|
|
195
|
+
if (!isOpen) {
|
|
196
|
+
savedRectRef.current = null;
|
|
197
|
+
savedTextRef.current = '';
|
|
198
|
+
}
|
|
199
|
+
}, [isOpen, range, selectedText]);
|
|
200
|
+
// Effective values: prefer live selection, fall back to saved snapshot
|
|
201
|
+
const effectiveRect = useMemo(() => range?.getBoundingClientRect() ?? savedRectRef.current ?? null, [range]);
|
|
202
|
+
const effectiveText = range ? selectedText : savedTextRef.current;
|
|
203
|
+
// Update floating reference position based on selection (or saved rect)
|
|
183
204
|
useLayoutEffect(() => {
|
|
184
205
|
setReference({
|
|
185
|
-
getBoundingClientRect: () =>
|
|
206
|
+
getBoundingClientRect: () => effectiveRect || new DOMRect(),
|
|
186
207
|
});
|
|
187
|
-
}, [setReference,
|
|
208
|
+
}, [setReference, effectiveRect]);
|
|
188
209
|
// Handle replace selection
|
|
189
210
|
const handleReplaceSelection = useCallback((text) => {
|
|
190
211
|
editor.update(() => {
|
|
@@ -219,8 +240,8 @@ export function ChatInlinePlugin({ protocol, isOpen, onClose, pendingPrompt, onP
|
|
|
219
240
|
}
|
|
220
241
|
});
|
|
221
242
|
}, [editor]);
|
|
222
|
-
// Don't render if not open or
|
|
223
|
-
if (!isOpen || range === null) {
|
|
243
|
+
// Don't render if not open, or if we have neither a live range nor a saved rect
|
|
244
|
+
if (!isOpen || (range === null && savedRectRef.current === null)) {
|
|
224
245
|
return null;
|
|
225
246
|
}
|
|
226
247
|
const portalTarget = portalContainer || document.body;
|
|
@@ -236,6 +257,6 @@ export function ChatInlinePlugin({ protocol, isOpen, onClose, pendingPrompt, onP
|
|
|
236
257
|
width: editor._rootElement
|
|
237
258
|
? editor._rootElement.getBoundingClientRect().width - MARGIN_X * 2
|
|
238
259
|
: 'auto',
|
|
239
|
-
}, children: _jsx(ChatInline, { selectedText:
|
|
260
|
+
}, children: _jsx(ChatInline, { selectedText: effectiveText, protocol: protocol, onReplaceSelection: handleReplaceSelection, onInsertInline: handleInsertInline, onInsertBelow: handleInsertBelow, onClose: onClose, onSaveSelection: saveSelection, onRestoreSelection: restoreSelection, pendingPrompt: pendingPrompt, onPendingPromptConsumed: onPendingPromptConsumed }) }), portalTarget);
|
|
240
261
|
}
|
|
241
262
|
export default ChatInlinePlugin;
|
package/lib/lexical/index.d.ts
CHANGED
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* @module lexical
|
|
5
5
|
*/
|
|
6
6
|
export { ChatInlinePlugin, type ChatInlinePluginProps, SAVE_SELECTION_COMMAND, RESTORE_SELECTION_COMMAND, } from './ChatInlinePlugin';
|
|
7
|
-
export { useChatInlineToolbarItems, type ChatInlineToolbarState, } from './useChatInlineToolbarItems';
|
|
7
|
+
export { useChatInlineToolbarItems, type ChatInlineToolbarOptions, type ChatInlineToolbarState, } from './useChatInlineToolbarItems';
|
|
@@ -18,11 +18,18 @@ export interface ChatInlineToolbarState {
|
|
|
18
18
|
/** Close the AI panel */
|
|
19
19
|
closeAi: () => void;
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Options for useChatInlineToolbarItems.
|
|
23
|
+
*/
|
|
24
|
+
export interface ChatInlineToolbarOptions {
|
|
25
|
+
/** When true the AI sparkle button is rendered in a disabled state. */
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
}
|
|
21
28
|
/**
|
|
22
29
|
* Hook that creates ToolbarItem[] for AI actions in the floating toolbar.
|
|
23
30
|
*
|
|
24
|
-
* Returns toolbar items (divider + AI
|
|
31
|
+
* Returns toolbar items (divider + AI sparkle button) and
|
|
25
32
|
* state for controlling the ChatInline panel.
|
|
26
33
|
*/
|
|
27
|
-
export declare function useChatInlineToolbarItems(): ChatInlineToolbarState;
|
|
34
|
+
export declare function useChatInlineToolbarItems(options?: ChatInlineToolbarOptions): ChatInlineToolbarState;
|
|
28
35
|
export default useChatInlineToolbarItems;
|
|
@@ -6,13 +6,14 @@
|
|
|
6
6
|
* useChatInlineToolbarItems - Hook that creates ToolbarItem[] for the
|
|
7
7
|
* FloatingTextFormatToolbarPlugin's extraItems prop.
|
|
8
8
|
*
|
|
9
|
-
* Registers an AI sparkle button
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* Registers an AI sparkle button in the floating inline toolbar.
|
|
10
|
+
* Clicking the sparkle button directly opens the ChatInlinePlugin
|
|
11
|
+
* floating panel, where users can type free-form AI prompts.
|
|
12
12
|
*
|
|
13
13
|
* Usage:
|
|
14
14
|
* ```tsx
|
|
15
|
-
* const { toolbarItems, isAiOpen,
|
|
15
|
+
* const { toolbarItems, isAiOpen, pendingPrompt, clearPendingPrompt, closeAi } =
|
|
16
|
+
* useChatInlineToolbarItems();
|
|
16
17
|
*
|
|
17
18
|
* <FloatingTextFormatToolbarPlugin
|
|
18
19
|
* anchorElem={floatingAnchorElem}
|
|
@@ -20,82 +21,25 @@
|
|
|
20
21
|
* extraItems={toolbarItems}
|
|
21
22
|
* />
|
|
22
23
|
*
|
|
23
|
-
*
|
|
24
|
+
* <ChatInlinePlugin
|
|
25
|
+
* isOpen={isAiOpen}
|
|
26
|
+
* onClose={closeAi}
|
|
27
|
+
* pendingPrompt={pendingPrompt}
|
|
28
|
+
* onPendingPromptConsumed={clearPendingPrompt}
|
|
29
|
+
* />
|
|
24
30
|
* ```
|
|
25
31
|
*
|
|
26
32
|
* @module lexical/useChatInlineToolbarItems
|
|
27
33
|
*/
|
|
28
34
|
import { useState, useMemo, useCallback } from 'react';
|
|
29
|
-
import { SparkleFillIcon
|
|
30
|
-
/**
|
|
31
|
-
* AI action groups for the toolbar dropdown.
|
|
32
|
-
*/
|
|
33
|
-
const AI_ACTIONS = {
|
|
34
|
-
modify: [
|
|
35
|
-
{
|
|
36
|
-
key: 'ai-improve',
|
|
37
|
-
label: 'Improve writing',
|
|
38
|
-
prompt: 'Improve the quality of the text',
|
|
39
|
-
icon: PencilIcon,
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
key: 'ai-fix',
|
|
43
|
-
label: 'Fix mistakes',
|
|
44
|
-
prompt: 'Fix any typos or general errors in the text',
|
|
45
|
-
icon: CheckIcon,
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
key: 'ai-simplify',
|
|
49
|
-
label: 'Simplify',
|
|
50
|
-
prompt: 'Shorten the text, simplifying it',
|
|
51
|
-
icon: XIcon,
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
key: 'ai-detail',
|
|
55
|
-
label: 'Add more detail',
|
|
56
|
-
prompt: 'Lengthen the text, going into more detail',
|
|
57
|
-
icon: PlusIcon,
|
|
58
|
-
},
|
|
59
|
-
],
|
|
60
|
-
generate: [
|
|
61
|
-
{
|
|
62
|
-
key: 'ai-summarise',
|
|
63
|
-
label: 'Summarise',
|
|
64
|
-
prompt: 'Summarise the text',
|
|
65
|
-
icon: CopyIcon,
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
key: 'ai-explain',
|
|
69
|
-
label: 'Explain',
|
|
70
|
-
prompt: 'Explain what the text is about',
|
|
71
|
-
icon: InfoIcon,
|
|
72
|
-
},
|
|
73
|
-
],
|
|
74
|
-
translate: [
|
|
75
|
-
'Arabic',
|
|
76
|
-
'Chinese',
|
|
77
|
-
'Dutch',
|
|
78
|
-
'English',
|
|
79
|
-
'French',
|
|
80
|
-
'German',
|
|
81
|
-
'Japanese',
|
|
82
|
-
'Korean',
|
|
83
|
-
'Portuguese',
|
|
84
|
-
'Spanish',
|
|
85
|
-
].map(lang => ({
|
|
86
|
-
key: `ai-translate-${lang.toLowerCase()}`,
|
|
87
|
-
label: lang,
|
|
88
|
-
prompt: `Translate text into the ${lang} language`,
|
|
89
|
-
icon: SyncIcon,
|
|
90
|
-
})),
|
|
91
|
-
};
|
|
35
|
+
import { SparkleFillIcon } from '@primer/octicons-react';
|
|
92
36
|
/**
|
|
93
37
|
* Hook that creates ToolbarItem[] for AI actions in the floating toolbar.
|
|
94
38
|
*
|
|
95
|
-
* Returns toolbar items (divider + AI
|
|
39
|
+
* Returns toolbar items (divider + AI sparkle button) and
|
|
96
40
|
* state for controlling the ChatInline panel.
|
|
97
41
|
*/
|
|
98
|
-
export function useChatInlineToolbarItems() {
|
|
42
|
+
export function useChatInlineToolbarItems(options) {
|
|
99
43
|
const [isAiOpen, setIsAiOpen] = useState(false);
|
|
100
44
|
const [pendingPrompt, setPendingPrompt] = useState(null);
|
|
101
45
|
const openAi = useCallback(() => {
|
|
@@ -112,27 +56,8 @@ export function useChatInlineToolbarItems() {
|
|
|
112
56
|
const clearPendingPrompt = useCallback(() => {
|
|
113
57
|
setPendingPrompt(null);
|
|
114
58
|
}, []);
|
|
59
|
+
const isDisabled = options?.disabled ?? false;
|
|
115
60
|
const toolbarItems = useMemo(() => {
|
|
116
|
-
const allOptions = [
|
|
117
|
-
...AI_ACTIONS.modify.map(action => ({
|
|
118
|
-
key: action.key,
|
|
119
|
-
label: action.label,
|
|
120
|
-
icon: action.icon,
|
|
121
|
-
onClick: () => submitPrompt(action.prompt),
|
|
122
|
-
})),
|
|
123
|
-
...AI_ACTIONS.generate.map(action => ({
|
|
124
|
-
key: action.key,
|
|
125
|
-
label: action.label,
|
|
126
|
-
icon: action.icon,
|
|
127
|
-
onClick: () => submitPrompt(action.prompt),
|
|
128
|
-
})),
|
|
129
|
-
...AI_ACTIONS.translate.map(action => ({
|
|
130
|
-
key: action.key,
|
|
131
|
-
label: action.label,
|
|
132
|
-
icon: action.icon,
|
|
133
|
-
onClick: () => submitPrompt(action.prompt),
|
|
134
|
-
})),
|
|
135
|
-
];
|
|
136
61
|
return [
|
|
137
62
|
{
|
|
138
63
|
key: 'ai-divider',
|
|
@@ -141,15 +66,18 @@ export function useChatInlineToolbarItems() {
|
|
|
141
66
|
},
|
|
142
67
|
{
|
|
143
68
|
key: 'ai-actions',
|
|
144
|
-
type: '
|
|
69
|
+
type: 'button',
|
|
145
70
|
order: 901,
|
|
146
71
|
ariaLabel: 'AI Actions',
|
|
147
|
-
title:
|
|
72
|
+
title: isDisabled
|
|
73
|
+
? 'Assign an agent to enable AI actions'
|
|
74
|
+
: 'AI Actions',
|
|
148
75
|
icon: SparkleFillIcon,
|
|
149
|
-
|
|
76
|
+
onClick: openAi,
|
|
77
|
+
disabled: isDisabled,
|
|
150
78
|
},
|
|
151
79
|
];
|
|
152
|
-
}, [
|
|
80
|
+
}, [openAi, isDisabled]);
|
|
153
81
|
return {
|
|
154
82
|
toolbarItems,
|
|
155
83
|
isAiOpen,
|