@rimori/client 1.0.3 → 1.0.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.
Files changed (135) hide show
  1. package/README.md +51 -0
  2. package/dist/components/CRUDModal.js +0 -1
  3. package/dist/components/ai/Assistant.d.ts +9 -0
  4. package/dist/components/ai/Assistant.js +59 -0
  5. package/dist/components/ai/Avatar.d.ts +11 -0
  6. package/dist/components/ai/Avatar.js +39 -0
  7. package/dist/components/ai/EmbeddedAssistent/AudioInputField.d.ts +7 -0
  8. package/dist/components/ai/EmbeddedAssistent/AudioInputField.js +38 -0
  9. package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.d.ts +7 -0
  10. package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.js +59 -0
  11. package/dist/components/ai/EmbeddedAssistent/TTS/MessageSender.d.ts +19 -0
  12. package/dist/components/ai/EmbeddedAssistent/TTS/MessageSender.js +86 -0
  13. package/dist/components/ai/EmbeddedAssistent/TTS/Player.d.ts +25 -0
  14. package/dist/components/ai/EmbeddedAssistent/TTS/Player.js +180 -0
  15. package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.d.ts +7 -0
  16. package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.js +45 -0
  17. package/dist/components/ai/utils.d.ts +6 -0
  18. package/dist/components/ai/utils.js +14 -0
  19. package/dist/components/audio/Playbutton.js +4 -5
  20. package/dist/components/avatar/Assistant.d.ts +9 -0
  21. package/dist/components/avatar/Assistant.js +59 -0
  22. package/dist/components/avatar/Avatar.d.ts +12 -0
  23. package/dist/components/avatar/Avatar.js +42 -0
  24. package/dist/components/avatar/EmbeddedAssistent/AudioInputField.d.ts +7 -0
  25. package/dist/components/avatar/EmbeddedAssistent/AudioInputField.js +38 -0
  26. package/dist/components/avatar/EmbeddedAssistent/CircleAudioAvatar.d.ts +7 -0
  27. package/dist/components/avatar/EmbeddedAssistent/CircleAudioAvatar.js +59 -0
  28. package/dist/components/avatar/EmbeddedAssistent/TTS/MessageSender.d.ts +19 -0
  29. package/dist/components/avatar/EmbeddedAssistent/TTS/MessageSender.js +84 -0
  30. package/dist/components/avatar/EmbeddedAssistent/TTS/Player.d.ts +25 -0
  31. package/dist/components/avatar/EmbeddedAssistent/TTS/Player.js +180 -0
  32. package/dist/components/avatar/EmbeddedAssistent/VoiceRecoder.d.ts +7 -0
  33. package/dist/components/avatar/EmbeddedAssistent/VoiceRecoder.js +45 -0
  34. package/dist/components/avatar/utils.d.ts +6 -0
  35. package/dist/components/avatar/utils.js +14 -0
  36. package/dist/components.d.ts +9 -0
  37. package/dist/components.js +10 -0
  38. package/dist/controller/AIController.d.ts +4 -3
  39. package/dist/controller/AIController.js +32 -8
  40. package/dist/controller/ObjectController.d.ts +2 -2
  41. package/dist/controller/ObjectController.js +4 -5
  42. package/dist/controller/SettingsController.d.ts +19 -10
  43. package/dist/controller/SettingsController.js +33 -26
  44. package/dist/controller/SharedContentController.js +6 -6
  45. package/dist/core.d.ts +9 -0
  46. package/dist/core.js +10 -0
  47. package/dist/hooks/UseChatHook.js +2 -2
  48. package/dist/index.d.ts +3 -2
  49. package/dist/index.js +4 -2
  50. package/dist/plugin/PluginController.d.ts +4 -12
  51. package/dist/plugin/PluginController.js +45 -70
  52. package/dist/plugin/RimoriClient.d.ts +85 -32
  53. package/dist/plugin/RimoriClient.js +98 -77
  54. package/dist/plugin/ThemeSetter.js +3 -3
  55. package/dist/plugin/fromRimori/EventBus.d.ts +98 -0
  56. package/dist/plugin/fromRimori/EventBus.js +240 -0
  57. package/dist/providers/PluginProvider.d.ts +1 -0
  58. package/dist/providers/PluginProvider.js +10 -12
  59. package/dist/worker/WorkerSetup.d.ts +6 -0
  60. package/dist/worker/WorkerSetup.js +80 -0
  61. package/package.json +17 -3
  62. package/src/components/CRUDModal.tsx +1 -3
  63. package/src/components/ai/Assistant.tsx +96 -0
  64. package/src/components/ai/Avatar.tsx +61 -0
  65. package/src/components/ai/EmbeddedAssistent/AudioInputField.tsx +64 -0
  66. package/src/components/ai/EmbeddedAssistent/CircleAudioAvatar.tsx +75 -0
  67. package/src/components/ai/EmbeddedAssistent/TTS/MessageSender.ts +91 -0
  68. package/src/components/ai/EmbeddedAssistent/TTS/Player.ts +192 -0
  69. package/src/components/ai/EmbeddedAssistent/VoiceRecoder.tsx +56 -0
  70. package/src/components/ai/utils.ts +23 -0
  71. package/src/components/audio/Playbutton.tsx +4 -5
  72. package/src/components.ts +10 -0
  73. package/src/controller/AIController.ts +84 -60
  74. package/src/controller/ObjectController.ts +4 -6
  75. package/src/controller/SettingsController.ts +49 -35
  76. package/src/controller/SharedContentController.ts +6 -6
  77. package/src/core.ts +10 -0
  78. package/src/hooks/UseChatHook.ts +2 -2
  79. package/src/index.ts +4 -2
  80. package/src/plugin/PluginController.ts +51 -76
  81. package/src/plugin/RimoriClient.ts +147 -85
  82. package/src/plugin/ThemeSetter.ts +3 -4
  83. package/src/plugin/fromRimori/EventBus.ts +301 -0
  84. package/src/plugin/fromRimori/readme.md +2 -0
  85. package/src/providers/PluginProvider.tsx +12 -14
  86. package/src/worker/WorkerSetup.ts +81 -0
  87. package/dist/CRUDModal.d.ts +0 -16
  88. package/dist/CRUDModal.js +0 -31
  89. package/dist/MarkdownEditor.d.ts +0 -8
  90. package/dist/MarkdownEditor.js +0 -46
  91. package/dist/audio/Playbutton.d.ts +0 -14
  92. package/dist/audio/Playbutton.js +0 -73
  93. package/dist/components/hooks/UseChatHook.d.ts +0 -15
  94. package/dist/components/hooks/UseChatHook.js +0 -21
  95. package/dist/controller/PluginController.d.ts +0 -14
  96. package/dist/controller/PluginController.js +0 -30
  97. package/dist/plugin/AIController copy.d.ts +0 -22
  98. package/dist/plugin/AIController copy.js +0 -68
  99. package/dist/plugin/AIController.d.ts +0 -22
  100. package/dist/plugin/AIController.js +0 -68
  101. package/dist/plugin/ObjectController.d.ts +0 -34
  102. package/dist/plugin/ObjectController.js +0 -77
  103. package/dist/plugin/SettingController.d.ts +0 -13
  104. package/dist/plugin/SettingController.js +0 -55
  105. package/dist/plugin/VoiceController.d.ts +0 -2
  106. package/dist/plugin/VoiceController.js +0 -27
  107. package/dist/providers/EventEmitter.d.ts +0 -11
  108. package/dist/providers/EventEmitter.js +0 -41
  109. package/dist/providers/EventEmitterContext.d.ts +0 -6
  110. package/dist/providers/EventEmitterContext.js +0 -19
  111. package/dist/utils/DifficultyConverter.d.ts +0 -3
  112. package/dist/utils/DifficultyConverter.js +0 -7
  113. package/dist/utils/constants.d.ts +0 -4
  114. package/dist/utils/constants.js +0 -12
  115. package/dist/utils/plugin/Client.d.ts +0 -72
  116. package/dist/utils/plugin/Client.js +0 -118
  117. package/dist/utils/plugin/PluginController.d.ts +0 -36
  118. package/dist/utils/plugin/PluginController.js +0 -119
  119. package/dist/utils/plugin/PluginUtils.d.ts +0 -2
  120. package/dist/utils/plugin/PluginUtils.js +0 -23
  121. package/dist/utils/plugin/RimoriClient.d.ts +0 -72
  122. package/dist/utils/plugin/RimoriClient.js +0 -118
  123. package/dist/utils/plugin/ThemeSetter.d.ts +0 -1
  124. package/dist/utils/plugin/ThemeSetter.js +0 -13
  125. package/dist/utils/plugin/WhereClauseBuilder.d.ts +0 -24
  126. package/dist/utils/plugin/WhereClauseBuilder.js +0 -79
  127. package/dist/utils/plugin/providers/EventEmitter.d.ts +0 -11
  128. package/dist/utils/plugin/providers/EventEmitter.js +0 -41
  129. package/dist/utils/plugin/providers/EventEmitterContext.d.ts +0 -6
  130. package/dist/utils/plugin/providers/EventEmitterContext.js +0 -19
  131. package/dist/utils/plugin/providers/PluginProvider.d.ts +0 -8
  132. package/dist/utils/plugin/providers/PluginProvider.js +0 -49
  133. package/src/providers/EventEmitter.ts +0 -48
  134. package/src/providers/EventEmitterContext.tsx +0 -27
  135. package/src/utils/constants.ts +0 -18
@@ -1,16 +1,18 @@
1
1
  import React, { createContext, useContext, ReactNode, useEffect, useState } from 'react';
2
2
  import { PluginController } from '../plugin/PluginController';
3
3
  import { RimoriClient } from '../plugin/RimoriClient';
4
- import { UserSettings } from '../controller/SettingsController';
4
+ import { EventBusHandler } from '../plugin/fromRimori/EventBus';
5
5
 
6
6
  interface PluginProviderProps {
7
7
  children: ReactNode;
8
+ pluginId: string;
8
9
  }
9
10
 
10
- const PluginContext = createContext<RimoriClient | null>(null);
11
+ EventBusHandler.getInstance("Plugin EventBus");
11
12
 
13
+ const PluginContext = createContext<RimoriClient | null>(null);
12
14
 
13
- export const PluginProvider: React.FC<PluginProviderProps> = ({ children }) => {
15
+ export const PluginProvider: React.FC<PluginProviderProps> = ({ children, pluginId }) => {
14
16
  const [plugin, setPlugin] = useState<RimoriClient | null>(null);
15
17
  const [contextMenuOnSelect, setContextMenuOnTextSelection] = useState(false);
16
18
 
@@ -22,21 +24,17 @@ export const PluginProvider: React.FC<PluginProviderProps> = ({ children }) => {
22
24
  if (lastHash !== window.location.hash) {
23
25
  lastHash = window.location.hash;
24
26
  console.log('url changed:', lastHash);
25
- plugin?.emit('urlChange', window.location.hash);
27
+ plugin?.event.emit('session.triggerUrlChange', window.location.hash);
26
28
  }
27
29
  }, 100);
28
- PluginController.getInstance().then(setPlugin);
30
+ PluginController.getInstance(pluginId).then(setPlugin);
29
31
  }, []);
30
32
 
31
33
  //check if context menu opens on text selection
32
34
  useEffect(() => {
33
35
  if (!plugin) return;
34
- plugin.getSettings<UserSettings>({
35
- languageLevel: "A1",
36
- motherTongue: "English",
37
- contextMenuOnSelect: false,
38
- }, "user").then((settings) => {
39
- setContextMenuOnTextSelection(settings.contextMenuOnSelect);
36
+ plugin.plugin.getUserInfo().then((userInfo) => {
37
+ setContextMenuOnTextSelection(userInfo.contextMenuOnSelect);
40
38
  }).catch(error => {
41
39
  console.error('Error fetching settings:', error);
42
40
  });
@@ -45,7 +43,7 @@ export const PluginProvider: React.FC<PluginProviderProps> = ({ children }) => {
45
43
  //detect page height change
46
44
  useEffect(() => {
47
45
  const body = document.body;
48
- const handleResize = () => plugin?.emit('heightAdjustment', body.clientHeight);
46
+ const handleResize = () => plugin?.event.emit('session.triggerHeightChange', body.clientHeight);
49
47
  body.addEventListener('resize', handleResize);
50
48
  handleResize();
51
49
  return () => body.removeEventListener('resize', handleResize);
@@ -68,7 +66,7 @@ export const PluginProvider: React.FC<PluginProviderProps> = ({ children }) => {
68
66
  if (selection) {
69
67
  e.preventDefault();
70
68
  // console.log('context menu handled', selection);
71
- plugin?.emit('contextMenu', { text: selection, x: e.clientX, y: e.clientY, open: true });
69
+ plugin?.event.emit('global.contextMenu.trigger', { text: selection, x: e.clientX, y: e.clientY, open: true });
72
70
  }
73
71
  };
74
72
 
@@ -77,7 +75,7 @@ export const PluginProvider: React.FC<PluginProviderProps> = ({ children }) => {
77
75
  const selection = window.getSelection()?.toString().trim();
78
76
  const open = !!selection && isSelecting;
79
77
  // console.log('Selection change, contextMenuOnSelect:', contextMenuOnSelect);
80
- plugin?.emit('contextMenu', { text: selection, x: lastMouseX, y: lastMouseY, open });
78
+ plugin?.event.emit('global.contextMenu.trigger', { text: selection, x: lastMouseX, y: lastMouseY, open });
81
79
  // }
82
80
  };
83
81
  const handleMouseUpDown = (e: MouseEvent) => {
@@ -0,0 +1,81 @@
1
+ import { RimoriClient } from "../plugin/RimoriClient";
2
+ import { PluginController } from "../plugin/PluginController";
3
+ import { EventBus, EventBusHandler, EventBusMessage } from "../plugin/fromRimori/EventBus";
4
+
5
+ let controller: RimoriClient | null = null;
6
+ const listeners: ((event: { data: { event: EventBusMessage, secret: string } }) => void)[] = [];
7
+ let debugEnabled = false;
8
+
9
+ /**
10
+ * Sets up the web worker for the plugin to be able receive and send messages to Rimori.
11
+ * @param init - The function containing the subscription logic.
12
+ */
13
+ export function setupWorker(init: (controller: RimoriClient) => void | Promise<void>) {
14
+ // Mock of the window object for the worker context to be able to use the PluginController.
15
+ const mockWindow = {
16
+ isWorker: true,
17
+ location: { search: '?secret=123' },
18
+ parent: {
19
+ postMessage: (message: { event: EventBusMessage }) => {
20
+ message.event.sender = "worker." + message.event.sender;
21
+ checkDebugMode(message.event);
22
+ logIfDebug('[Worker] sending event to Rimori', message.event);
23
+ self.postMessage(message)
24
+ }
25
+ },
26
+ addEventListener: (_: string, listener: any) => {
27
+ listeners.push(listener);
28
+ },
29
+ APP_CONFIG: {
30
+ SUPABASE_URL: 'NOT_SET',
31
+ SUPABASE_ANON_KEY: 'NOT_SET',
32
+ },
33
+ };
34
+
35
+ // Assign the mock to globalThis.
36
+ Object.assign(globalThis, { window: mockWindow });
37
+
38
+ EventBusHandler.getInstance("Worker EventBus");
39
+
40
+ // Handle init message from Rimori.
41
+ self.onmessage = async (response: MessageEvent) => {
42
+ checkDebugMode(response.data);
43
+ logIfDebug('[Worker] message received', response.data);
44
+
45
+ const event = response.data as EventBusMessage;
46
+
47
+ if (event.topic === 'global.worker.requestInit') {
48
+ if (!controller) {
49
+ mockWindow.APP_CONFIG.SUPABASE_URL = event.data.supabaseUrl;
50
+ mockWindow.APP_CONFIG.SUPABASE_ANON_KEY = event.data.supabaseAnonKey;
51
+ controller = await PluginController.getInstance(event.data.pluginId);
52
+ logIfDebug('[Worker] Worker initialized.');
53
+ await init(controller);
54
+ logIfDebug('[Worker] Plugin listeners initialized.');
55
+ }
56
+ const initEvent: EventBusMessage = {
57
+ timestamp: new Date().toISOString(),
58
+ eventId: event.eventId,
59
+ sender: "worker." + event.sender,
60
+ topic: 'global.worker.requestInit',
61
+ data: { success: true },
62
+ debug: debugEnabled
63
+ };
64
+ return self.postMessage({ secret: "123", event: initEvent });
65
+ }
66
+ listeners.forEach(listener => listener({ data: { event: response.data, secret: "123" } }));
67
+ };
68
+ }
69
+
70
+ function checkDebugMode(event: EventBusMessage) {
71
+ if (event.topic === 'global.system.requestDebug' || event.debug) {
72
+ debugEnabled = true;
73
+ EventBus.emit("worker", "global.system.requestDebug");
74
+ }
75
+ }
76
+
77
+ function logIfDebug(...args: any[]) {
78
+ if (debugEnabled) {
79
+ console.debug('[Worker] ' + args[0], ...args.slice(1));
80
+ }
81
+ }
@@ -1,16 +0,0 @@
1
- interface Props {
2
- title: string;
3
- show?: boolean;
4
- className?: string;
5
- closeAble?: boolean;
6
- children: React.ReactNode;
7
- actionbuttons: ActionButton[];
8
- buttonText?: string | React.ReactNode;
9
- }
10
- interface ActionButton {
11
- text: string;
12
- onClick: () => void;
13
- closeModal?: boolean;
14
- }
15
- export declare function CRUDModal({ actionbuttons, children, title, buttonText, className, closeAble, show }: Props): import("react/jsx-runtime").JSX.Element;
16
- export {};
package/dist/CRUDModal.js DELETED
@@ -1,31 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useEffect, useState, useRef } from "react";
4
- export function CRUDModal({ actionbuttons, children, title, buttonText, className, closeAble = true, show = false }) {
5
- const [openModal, setOpenModal] = useState(show);
6
- const dialogRef = useRef(null);
7
- useEffect(() => {
8
- var _a, _b;
9
- if (show) {
10
- (_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.showModal();
11
- }
12
- else {
13
- (_b = dialogRef.current) === null || _b === void 0 ? void 0 : _b.close();
14
- }
15
- setOpenModal(show);
16
- }, [show]);
17
- const handleClose = () => {
18
- var _a;
19
- setOpenModal(false);
20
- (_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.close();
21
- };
22
- return (_jsxs(_Fragment, { children: [!!buttonText && _jsx("button", { className: className, onClick: () => {
23
- var _a;
24
- setOpenModal(true);
25
- (_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.showModal();
26
- }, children: buttonText }), _jsxs("dialog", { ref: dialogRef, className: "bg-gray-400 rounded-lg font-normal", onClose: handleClose, children: [_jsxs("div", { className: "bg-gray-500 text-xl flex flex-row justify-between p-3 items-start font-bold", children: [_jsx("h2", { children: title }), closeAble && _jsx("button", { onClick: handleClose, children: "\u00D7" })] }), _jsx("div", { className: "modal-body p-2", children: children }), _jsx("div", { className: "modal-footer px-2 py-2 flex flex-row gap-2 border-t-2", children: actionbuttons.map(({ onClick, text, closeModal = true }, index) => (_jsx("button", { className: " bg-blue-500 hover:bg-blue-600 dark:border-gray-900 rounded-md py-2 px-4 dark:text-white font-bold", onClick: () => {
27
- if (closeModal)
28
- handleClose();
29
- onClick();
30
- }, children: text }, index))) })] })] }));
31
- }
@@ -1,8 +0,0 @@
1
- interface Props {
2
- content?: string;
3
- editable: boolean;
4
- className?: string;
5
- onUpdate?: (content: string) => void;
6
- }
7
- export declare const MarkdownEditor: (props: Props) => import("react/jsx-runtime").JSX.Element;
8
- export {};
@@ -1,46 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Markdown } from 'tiptap-markdown';
3
- import StarterKit from "@tiptap/starter-kit";
4
- import { PiCodeBlock } from "react-icons/pi";
5
- import { TbBlockquote } from "react-icons/tb";
6
- import { GoListOrdered } from "react-icons/go";
7
- import { AiOutlineUnorderedList } from "react-icons/ai";
8
- import { EditorProvider, useCurrentEditor } from "@tiptap/react";
9
- import { LuHeading1, LuHeading2, LuHeading3 } from "react-icons/lu";
10
- import { FaBold, FaCode, FaItalic, FaParagraph, FaStrikethrough } from "react-icons/fa";
11
- const EditorButton = ({ action, isActive, label, disabled }) => {
12
- const { editor } = useCurrentEditor();
13
- if (!editor) {
14
- return null;
15
- }
16
- if (action.includes("heading")) {
17
- const level = parseInt(action[action.length - 1]);
18
- return (_jsx("button", { onClick: () => editor.chain().focus().toggleHeading({ level: level }).run(), className: `pl-2 ${isActive ? "is-active" : ""}`, children: label }));
19
- }
20
- return (_jsx("button", { onClick: () => editor.chain().focus()[action]().run(), disabled: disabled ? !editor.can().chain().focus()[action]().run() : false, className: `pl-2 ${isActive ? "is-active" : ""}`, children: label }));
21
- };
22
- const MenuBar = () => {
23
- const { editor } = useCurrentEditor();
24
- if (!editor) {
25
- return null;
26
- }
27
- return (_jsxs("div", { className: "bg-gray-400 dark:bg-gray-800 dark:text-white text-lg flex flex-row flex-wrap items-center p-1", children: [_jsx(EditorButton, { action: "toggleBold", isActive: editor.isActive("bold"), label: _jsx(FaBold, {}), disabled: true }), _jsx(EditorButton, { action: "toggleItalic", isActive: editor.isActive("italic"), label: _jsx(FaItalic, {}), disabled: true }), _jsx(EditorButton, { action: "toggleStrike", isActive: editor.isActive("strike"), label: _jsx(FaStrikethrough, {}), disabled: true }), _jsx(EditorButton, { action: "toggleCode", isActive: editor.isActive("code"), label: _jsx(FaCode, {}), disabled: true }), _jsx(EditorButton, { action: "setParagraph", isActive: editor.isActive("paragraph"), label: _jsx(FaParagraph, {}) }), _jsx(EditorButton, { action: 'setHeading1', isActive: editor.isActive("heading", { level: 1 }), label: _jsx(LuHeading1, { size: "24px" }) }), _jsx(EditorButton, { action: 'setHeading2', isActive: editor.isActive("heading", { level: 2 }), label: _jsx(LuHeading2, { size: "24px" }) }), _jsx(EditorButton, { action: 'setHeading3', isActive: editor.isActive("heading", { level: 3 }), label: _jsx(LuHeading3, { size: "24px" }) }), _jsx(EditorButton, { action: "toggleBulletList", isActive: editor.isActive("bulletList"), label: _jsx(AiOutlineUnorderedList, { size: "24px" }) }), _jsx(EditorButton, { action: "toggleOrderedList", isActive: editor.isActive("orderedList"), label: _jsx(GoListOrdered, { size: "24px" }) }), _jsx(EditorButton, { action: "toggleCodeBlock", isActive: editor.isActive("codeBlock"), label: _jsx(PiCodeBlock, { size: "24px" }) }), _jsx(EditorButton, { action: "toggleBlockquote", isActive: editor.isActive("blockquote"), label: _jsx(TbBlockquote, { size: "24px" }) })] }));
28
- };
29
- const extensions = [
30
- StarterKit.configure({
31
- bulletList: {
32
- keepMarks: true,
33
- keepAttributes: false,
34
- },
35
- orderedList: {
36
- keepMarks: true,
37
- keepAttributes: false,
38
- },
39
- }),
40
- Markdown,
41
- ];
42
- export const MarkdownEditor = (props) => {
43
- return (_jsx("div", { className: "text-md border border-gray-800 overflow-hidden " + props.className, style: { borderWidth: props.editable ? 1 : 0 }, children: _jsx(EditorProvider, { slotBefore: props.editable ? _jsx(MenuBar, {}) : null, extensions: extensions, content: props.content, editable: props.editable, onUpdate: (e) => {
44
- props.onUpdate && props.onUpdate(e.editor.storage.markdown.getMarkdown());
45
- } }, (props.editable ? "editable" : "readonly") + props.content) }));
46
- };
@@ -1,14 +0,0 @@
1
- import React from 'react';
2
- type AudioPlayerProps = {
3
- text: string;
4
- voice?: string;
5
- language?: string;
6
- playOnMount?: boolean;
7
- initialSpeed?: number;
8
- enableSpeedAdjustment?: boolean;
9
- playListenerEvent?: string;
10
- };
11
- export declare const AudioPlayOptions: number[];
12
- export type AudioPlayOptionType = 0.8 | 0.9 | 1.0 | 1.1 | 1.2 | 1.5;
13
- export declare const AudioPlayer: React.FC<AudioPlayerProps>;
14
- export {};
@@ -1,73 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
- import { useState, useEffect } from 'react';
12
- import { FaPlayCircle, FaStopCircle } from "react-icons/fa";
13
- import { usePlugin } from "../utils/plugin/providers/PluginProvider";
14
- import Spinner from '../components/Spinner';
15
- import { EmitterSingleton } from '../utils/plugin/providers/EventEmitter';
16
- export const AudioPlayOptions = [0.8, 0.9, 1.0, 1.1, 1.2, 1.5];
17
- let isFetchingAudio = false;
18
- export const AudioPlayer = ({ text, voice, language, playListenerEvent, initialSpeed = 1.0, playOnMount = false, enableSpeedAdjustment = false, }) => {
19
- const [audioUrl, setAudioUrl] = useState(null);
20
- const [speed, setSpeed] = useState(initialSpeed);
21
- const [isPlaying, setIsPlaying] = useState(false);
22
- const [isLoading, setIsLoading] = useState(false);
23
- const { getVoiceResponse, } = usePlugin();
24
- const emitter = EmitterSingleton;
25
- useEffect(() => {
26
- if (!playListenerEvent)
27
- return;
28
- emitter.on(playListenerEvent, () => togglePlayback());
29
- }, [playListenerEvent]);
30
- // Function to generate audio from text using API
31
- const generateAudio = () => __awaiter(void 0, void 0, void 0, function* () {
32
- setIsLoading(true);
33
- const blob = yield getVoiceResponse(text, voice || (language ? "aws_default" : "openai_alloy"), 1, language);
34
- setAudioUrl(URL.createObjectURL(blob));
35
- setIsLoading(false);
36
- });
37
- // Effect to play audio when audioUrl changes and play state is true
38
- useEffect(() => {
39
- if (!audioUrl || !isPlaying)
40
- return;
41
- const audio = new Audio(audioUrl);
42
- audio.playbackRate = speed;
43
- audio.play().then(() => {
44
- audio.onended = () => {
45
- setIsPlaying(false);
46
- isFetchingAudio = false;
47
- };
48
- }).catch(e => {
49
- console.warn("Error playing audio:", e);
50
- setIsPlaying(false);
51
- });
52
- return () => {
53
- audio.pause();
54
- URL.revokeObjectURL(audioUrl);
55
- };
56
- }, [audioUrl, isPlaying, speed]);
57
- const togglePlayback = () => {
58
- if (!isPlaying && !audioUrl) {
59
- generateAudio().then(() => setIsPlaying(true));
60
- }
61
- else {
62
- setIsPlaying((prev) => !prev);
63
- }
64
- };
65
- useEffect(() => {
66
- if (!playOnMount || isFetchingAudio)
67
- return;
68
- isFetchingAudio = true;
69
- // console.log("playOnMount", playOnMount);
70
- togglePlayback();
71
- }, [playOnMount]);
72
- return (_jsx("div", { className: "group relative", children: _jsxs("div", { className: 'flex flex-row items-end', children: [_jsx("button", { className: "text-gray-500", onClick: togglePlayback, disabled: isLoading, children: isLoading ? _jsx(Spinner, {}) : isPlaying ? _jsx(FaStopCircle, { size: "25px" }) : _jsx(FaPlayCircle, { size: "25px" }) }), enableSpeedAdjustment && (_jsxs("div", { className: "ml-1 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex flex-row text-sm text-gray-500", children: [_jsx("span", { className: 'pr-1', children: "Speed: " }), _jsx("select", { value: speed, className: 'appearance-none cursor-pointer pr-0 p-0 rounded shadow leading-tight focus:outline-none focus:bg-gray-800 focus:ring bg-transparent border-0', onChange: (e) => setSpeed(parseFloat(e.target.value)), disabled: isLoading, children: AudioPlayOptions.map((s) => (_jsx("option", { value: s, children: s }, s))) })] }))] }) }));
73
- };
@@ -1,15 +0,0 @@
1
- import React from "react";
2
- import { ToolInvocation, Tool } from "../../utils/plugin/PluginController";
3
- export interface Message {
4
- role: string;
5
- content: string;
6
- id: string | number;
7
- toolInvocations?: ToolInvocation[];
8
- }
9
- export declare function useChat(tools?: Tool[]): {
10
- messages: Message[];
11
- append: (appendMessages: Message[]) => void;
12
- isLoading: boolean;
13
- setMessages: React.Dispatch<React.SetStateAction<Message[]>>;
14
- lastMessage: Message | undefined;
15
- };
@@ -1,21 +0,0 @@
1
- import React from "react";
2
- import { usePlugin } from "../../utils/plugin/providers/PluginProvider";
3
- export function useChat(tools) {
4
- const [messages, setMessages] = React.useState([]);
5
- const [isLoading, setIsLoading] = React.useState(false);
6
- const { getAIResponseStream } = usePlugin();
7
- const append = (appendMessages) => {
8
- getAIResponseStream([...messages, ...appendMessages], (id, message, finished, toolInvocations) => {
9
- const lastMessage = messages[messages.length - 1];
10
- setIsLoading(!finished);
11
- if ((lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.id) === id) {
12
- lastMessage.content = message;
13
- setMessages([...messages, lastMessage]);
14
- }
15
- else {
16
- setMessages([...messages, ...appendMessages, { id, role: 'assistant', content: message, toolInvocations }]);
17
- }
18
- }, tools);
19
- };
20
- return { messages, append, isLoading, setMessages, lastMessage: messages[messages.length - 1] };
21
- }
@@ -1,14 +0,0 @@
1
- import { SupabaseClient } from '@supabase/supabase-js';
2
- export interface Plugin {
3
- id: string;
4
- title: string;
5
- icon_url: string;
6
- website: string;
7
- context_menu_actions: string;
8
- plugin_pages: string;
9
- sidebar_pages: string;
10
- settings_page: string;
11
- version: string;
12
- external_hosted_url: string;
13
- }
14
- export declare function getPlugins(supabase: SupabaseClient): Promise<Plugin[]>;
@@ -1,30 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- export function getPlugins(supabase) {
11
- return __awaiter(this, void 0, void 0, function* () {
12
- let { data, error } = yield supabase.from('plugins').select('*');
13
- if (error) {
14
- console.error(error);
15
- return [];
16
- }
17
- return (data || []).map((plugin) => ({
18
- id: plugin.id,
19
- title: plugin.title,
20
- icon_url: plugin.icon_url,
21
- website: plugin.website,
22
- context_menu_actions: plugin.context_menu_actions,
23
- plugin_pages: plugin.plugin_pages,
24
- sidebar_pages: plugin.sidebar_pages,
25
- settings_page: plugin.settings_page,
26
- version: plugin.version,
27
- external_hosted_url: plugin.external_hosted_url,
28
- }));
29
- });
30
- }
@@ -1,22 +0,0 @@
1
- export interface ToolInvocation {
2
- toolName: string;
3
- args: Record<string, string>;
4
- }
5
- export interface Tool {
6
- name: string;
7
- description: string;
8
- parameters: {
9
- name: string;
10
- type: "string" | "number" | "boolean";
11
- description: string;
12
- }[];
13
- }
14
- export interface Message {
15
- id: string;
16
- role: string;
17
- content: string;
18
- toolInvocations?: ToolInvocation[];
19
- }
20
- export declare function generateText(messages: Message[], tools: Tool[], token: string): Promise<any>;
21
- export type OnLLMResponse = (id: string, response: string, finished: boolean, toolInvocations?: ToolInvocation[]) => void;
22
- export declare function streamChatGPT(messages: Message[], tools: Tool[], onResponse: OnLLMResponse, token: string): Promise<void>;
@@ -1,68 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { env } from "../utils/constants";
11
- export function generateText(messages, tools, token) {
12
- return __awaiter(this, void 0, void 0, function* () {
13
- const response = yield fetch(`${env.SUPABASE_URL}/functions/v1/llm`, {
14
- method: 'POST',
15
- body: JSON.stringify({ messages, tools }),
16
- headers: { 'Authorization': `Bearer ${token}` }
17
- });
18
- return yield response.json();
19
- });
20
- }
21
- export function streamChatGPT(messages, tools, onResponse, token) {
22
- return __awaiter(this, void 0, void 0, function* () {
23
- const messageId = Math.random().toString(36).substring(3);
24
- const response = yield fetch(`${env.SUPABASE_URL}/functions/v1/llm`, {
25
- method: 'POST',
26
- body: JSON.stringify({ messages, tools, stream: true }),
27
- headers: { 'Authorization': `Bearer ${token}` }
28
- });
29
- if (!response.body) {
30
- console.error('No response body.');
31
- return;
32
- }
33
- const reader = response.body.getReader();
34
- const decoder = new TextDecoder('utf-8');
35
- let content = "";
36
- let done = false;
37
- let toolInvocations = [];
38
- while (!done) {
39
- const { value } = yield reader.read();
40
- if (value) {
41
- const chunk = decoder.decode(value, { stream: true });
42
- const lines = chunk.split('\n').filter(line => line.trim() !== '');
43
- for (const line of lines) {
44
- const data = line.substring(3, line.length - 1);
45
- const command = line.substring(0, 1);
46
- // console.log("data: ", { line, data, command });
47
- if (command === '0') {
48
- content += data;
49
- // console.log("AI response:", content);
50
- //content \n\n should be real line break when message is displayed
51
- onResponse(messageId, content.replace(/\\n/g, '\n'), false);
52
- }
53
- else if (command === 'd') {
54
- // console.log("AI usage:", JSON.parse(line.substring(2)));
55
- done = true;
56
- break;
57
- }
58
- else if (command === '9') {
59
- // console.log("tool call:", JSON.parse(line.substring(2)));
60
- // console.log("tools", tools);
61
- toolInvocations.push(JSON.parse(line.substring(2)));
62
- }
63
- }
64
- }
65
- }
66
- onResponse(messageId, content.replace(/\\n/g, '\n'), true, toolInvocations);
67
- });
68
- }
@@ -1,22 +0,0 @@
1
- export interface ToolInvocation {
2
- toolName: string;
3
- args: Record<string, string>;
4
- }
5
- export interface Tool {
6
- name: string;
7
- description: string;
8
- parameters: {
9
- name: string;
10
- type: "string" | "number" | "boolean";
11
- description: string;
12
- }[];
13
- }
14
- export interface Message {
15
- id: string;
16
- role: string;
17
- content: string;
18
- toolInvocations?: ToolInvocation[];
19
- }
20
- export declare function generateText(messages: Message[], tools: Tool[], token: string): Promise<any>;
21
- export type OnLLMResponse = (id: string, response: string, finished: boolean, toolInvocations?: ToolInvocation[]) => void;
22
- export declare function streamChatGPT(messages: Message[], tools: Tool[], onResponse: OnLLMResponse, token: string): Promise<void>;
@@ -1,68 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { env } from "../utils/constants";
11
- export function generateText(messages, tools, token) {
12
- return __awaiter(this, void 0, void 0, function* () {
13
- const response = yield fetch(`${env.SUPABASE_URL}/functions/v1/llm`, {
14
- method: 'POST',
15
- body: JSON.stringify({ messages, tools }),
16
- headers: { 'Authorization': `Bearer ${token}` }
17
- });
18
- return yield response.json();
19
- });
20
- }
21
- export function streamChatGPT(messages, tools, onResponse, token) {
22
- return __awaiter(this, void 0, void 0, function* () {
23
- const messageId = Math.random().toString(36).substring(3);
24
- const response = yield fetch(`${env.SUPABASE_URL}/functions/v1/llm`, {
25
- method: 'POST',
26
- body: JSON.stringify({ messages, tools, stream: true }),
27
- headers: { 'Authorization': `Bearer ${token}` }
28
- });
29
- if (!response.body) {
30
- console.error('No response body.');
31
- return;
32
- }
33
- const reader = response.body.getReader();
34
- const decoder = new TextDecoder('utf-8');
35
- let content = "";
36
- let done = false;
37
- let toolInvocations = [];
38
- while (!done) {
39
- const { value } = yield reader.read();
40
- if (value) {
41
- const chunk = decoder.decode(value, { stream: true });
42
- const lines = chunk.split('\n').filter(line => line.trim() !== '');
43
- for (const line of lines) {
44
- const data = line.substring(3, line.length - 1);
45
- const command = line.substring(0, 1);
46
- // console.log("data: ", { line, data, command });
47
- if (command === '0') {
48
- content += data;
49
- // console.log("AI response:", content);
50
- //content \n\n should be real line break when message is displayed
51
- onResponse(messageId, content.replace(/\\n/g, '\n'), false);
52
- }
53
- else if (command === 'd') {
54
- // console.log("AI usage:", JSON.parse(line.substring(2)));
55
- done = true;
56
- break;
57
- }
58
- else if (command === '9') {
59
- // console.log("tool call:", JSON.parse(line.substring(2)));
60
- // console.log("tools", tools);
61
- toolInvocations.push(JSON.parse(line.substring(2)));
62
- }
63
- }
64
- }
65
- }
66
- onResponse(messageId, content.replace(/\\n/g, '\n'), true, toolInvocations);
67
- });
68
- }
@@ -1,34 +0,0 @@
1
- type PrimitiveType = 'string' | 'number' | 'boolean';
2
- type ObjectToolParameterType = PrimitiveType | {
3
- [key: string]: ObjectToolParameter;
4
- } | [{
5
- [key: string]: ObjectToolParameter;
6
- }];
7
- interface ObjectToolParameter {
8
- type: ObjectToolParameterType;
9
- description?: string;
10
- enum?: string[];
11
- }
12
- export type ObjectTool = {
13
- [key: string]: ObjectToolParameter;
14
- };
15
- export interface ObjectRequest {
16
- /**
17
- * The tools that the AI can use.
18
- */
19
- tool: ObjectTool;
20
- /**
21
- * High level instructions for the AI to follow. Behaviour, tone, restrictions, etc.
22
- * Example: "Act like a recipe writer."
23
- */
24
- behaviour?: string;
25
- /**
26
- * The specific instruction for the AI to follow.
27
- * Example: "Generate a recipe using chicken, rice and vegetables."
28
- */
29
- instructions: string;
30
- }
31
- export declare function generateObject(request: ObjectRequest, token: string): Promise<any>;
32
- export type OnLLMResponse = (id: string, response: string, finished: boolean, toolInvocations?: any[]) => void;
33
- export declare function streamObject(request: ObjectRequest, onResponse: OnLLMResponse, token: string): Promise<void>;
34
- export {};