@rimori/client 1.4.0 → 1.4.3
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/README.md +77 -71
- package/dist/cli/scripts/init/dev-registration.d.ts +1 -1
- package/dist/cli/scripts/init/dev-registration.js +4 -4
- package/dist/cli/scripts/init/main.js +1 -1
- package/dist/cli/scripts/init/package-setup.d.ts +1 -1
- package/dist/cli/scripts/init/package-setup.js +3 -3
- package/dist/cli/scripts/init/router-transformer.js +19 -12
- package/dist/cli/scripts/init/vite-config.d.ts +2 -2
- package/dist/cli/scripts/init/vite-config.js +2 -2
- package/dist/cli/scripts/release/release-config-upload.js +9 -9
- package/dist/cli/scripts/release/release-db-update.d.ts +1 -1
- package/dist/cli/scripts/release/release-db-update.js +9 -9
- package/dist/cli/scripts/release/release-file-upload.js +1 -1
- package/dist/cli/scripts/release/release.js +2 -2
- package/dist/components/CRUDModal.d.ts +1 -1
- package/dist/components/CRUDModal.js +3 -3
- package/dist/components/MarkdownEditor.js +16 -16
- package/dist/components/Spinner.js +2 -2
- package/dist/components/ai/Assistant.js +7 -8
- package/dist/components/ai/Avatar.d.ts +2 -2
- package/dist/components/ai/Avatar.js +10 -5
- package/dist/components/ai/EmbeddedAssistent/AudioInputField.js +5 -6
- package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.d.ts +1 -1
- package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.js +1 -2
- package/dist/components/ai/EmbeddedAssistent/TTS/MessageSender.d.ts +1 -2
- package/dist/components/ai/EmbeddedAssistent/TTS/MessageSender.js +4 -2
- package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.js +2 -3
- package/dist/components/audio/Playbutton.js +10 -7
- package/dist/components/components/ContextMenu.d.ts +1 -1
- package/dist/components/components/ContextMenu.js +19 -16
- package/dist/components.d.ts +10 -10
- package/dist/components.js +10 -10
- package/dist/core/controller/AIController.d.ts +2 -2
- package/dist/core/controller/AIController.js +12 -12
- package/dist/core/controller/ExerciseController.d.ts +2 -2
- package/dist/core/controller/ExerciseController.js +2 -2
- package/dist/core/controller/ObjectController.js +5 -5
- package/dist/core/controller/SettingsController.d.ts +22 -7
- package/dist/core/controller/SettingsController.js +73 -8
- package/dist/core/controller/SharedContentController.d.ts +3 -3
- package/dist/core/controller/SharedContentController.js +38 -20
- package/dist/core/controller/VoiceController.js +6 -4
- package/dist/core/core.d.ts +15 -15
- package/dist/core/core.js +7 -7
- package/dist/fromRimori/EventBus.js +23 -23
- package/dist/fromRimori/PluginTypes.d.ts +4 -4
- package/dist/hooks/UseChatHook.d.ts +3 -3
- package/dist/hooks/UseChatHook.js +9 -3
- package/dist/index.d.ts +10 -10
- package/dist/index.js +9 -9
- package/dist/plugin/AccomplishmentHandler.d.ts +5 -5
- package/dist/plugin/AccomplishmentHandler.js +31 -27
- package/dist/plugin/AudioController.d.ts +1 -1
- package/dist/plugin/AudioController.js +6 -6
- package/dist/plugin/Logger.js +15 -13
- package/dist/plugin/PluginController.d.ts +7 -1
- package/dist/plugin/PluginController.js +32 -27
- package/dist/plugin/RimoriClient.d.ts +17 -18
- package/dist/plugin/RimoriClient.js +31 -31
- package/dist/plugin/StandaloneClient.d.ts +1 -1
- package/dist/plugin/StandaloneClient.js +35 -16
- package/dist/plugin/ThemeSetter.js +4 -4
- package/dist/providers/PluginProvider.js +44 -14
- package/dist/utils/Language.js +57 -57
- package/dist/utils/PluginUtils.js +3 -3
- package/dist/utils/difficultyConverter.d.ts +1 -1
- package/dist/utils/difficultyConverter.js +1 -1
- package/dist/utils/endpoint.js +2 -2
- package/dist/worker/WorkerSetup.d.ts +1 -1
- package/dist/worker/WorkerSetup.js +6 -6
- package/example/docs/devdocs.md +50 -40
- package/example/docs/overview.md +1 -1
- package/example/docs/userdocs.md +4 -1
- package/example/rimori.config.ts +51 -49
- package/example/worker/vite.config.ts +3 -3
- package/example/worker/worker.ts +2 -2
- package/package.json +14 -8
- package/prettier.config.js +1 -1
- package/src/cli/scripts/init/dev-registration.ts +5 -8
- package/src/cli/scripts/init/env-setup.ts +1 -1
- package/src/cli/scripts/init/file-operations.ts +1 -1
- package/src/cli/scripts/init/html-cleaner.ts +2 -5
- package/src/cli/scripts/init/main.ts +16 -13
- package/src/cli/scripts/init/package-setup.ts +11 -15
- package/src/cli/scripts/init/router-transformer.ts +40 -37
- package/src/cli/scripts/init/tailwind-config.ts +17 -26
- package/src/cli/scripts/init/vite-config.ts +3 -3
- package/src/cli/scripts/release/release-config-upload.ts +11 -11
- package/src/cli/scripts/release/release-db-update.ts +12 -12
- package/src/cli/scripts/release/release-file-upload.ts +2 -2
- package/src/cli/scripts/release/release.ts +4 -4
- package/src/cli/types/DatabaseTypes.ts +2 -10
- package/src/components/CRUDModal.tsx +64 -48
- package/src/components/MarkdownEditor.tsx +58 -27
- package/src/components/Spinner.tsx +24 -17
- package/src/components/ai/Assistant.tsx +70 -70
- package/src/components/ai/Avatar.tsx +17 -14
- package/src/components/ai/EmbeddedAssistent/AudioInputField.tsx +63 -54
- package/src/components/ai/EmbeddedAssistent/CircleAudioAvatar.tsx +14 -5
- package/src/components/ai/EmbeddedAssistent/TTS/MessageSender.ts +75 -74
- package/src/components/ai/EmbeddedAssistent/TTS/Player.ts +3 -4
- package/src/components/ai/EmbeddedAssistent/VoiceRecoder.tsx +109 -94
- package/src/components/ai/utils.ts +4 -4
- package/src/components/audio/Playbutton.tsx +101 -93
- package/src/components/components/ContextMenu.tsx +47 -35
- package/src/components.ts +10 -10
- package/src/core/controller/AIController.ts +29 -19
- package/src/core/controller/ExerciseController.ts +16 -23
- package/src/core/controller/ObjectController.ts +15 -10
- package/src/core/controller/SettingsController.ts +89 -16
- package/src/core/controller/SharedContentController.ts +80 -44
- package/src/core/controller/VoiceController.ts +10 -8
- package/src/core/core.ts +15 -16
- package/src/fromRimori/EventBus.ts +76 -47
- package/src/fromRimori/PluginTypes.ts +26 -17
- package/src/fromRimori/readme.md +2 -2
- package/src/hooks/UseChatHook.ts +25 -15
- package/src/index.ts +10 -10
- package/src/plugin/AccomplishmentHandler.ts +53 -35
- package/src/plugin/AudioController.ts +18 -12
- package/src/plugin/Logger.ts +28 -21
- package/src/plugin/PluginController.ts +60 -44
- package/src/plugin/RimoriClient.ts +102 -72
- package/src/plugin/StandaloneClient.ts +51 -24
- package/src/plugin/ThemeSetter.ts +5 -5
- package/src/providers/PluginProvider.tsx +90 -36
- package/src/style.scss +3 -3
- package/src/utils/Language.ts +58 -58
- package/src/utils/PluginUtils.ts +16 -20
- package/src/utils/difficultyConverter.ts +2 -2
- package/src/utils/endpoint.ts +3 -2
- package/src/worker/WorkerSetup.ts +8 -9
- package/tsconfig.json +2 -4
package/dist/core/core.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export { EventBusMessage } from
|
|
9
|
-
export { Buddy, UserInfo } from
|
|
10
|
-
export { SharedContent } from
|
|
11
|
-
export { Exercise, TriggerAction } from
|
|
12
|
-
export { Message, OnLLMResponse, ToolInvocation } from
|
|
13
|
-
export { MacroAccomplishmentPayload, MicroAccomplishmentPayload } from
|
|
14
|
-
export { Tool } from
|
|
15
|
-
export { SharedContentObjectRequest } from
|
|
1
|
+
export * from '../fromRimori/PluginTypes';
|
|
2
|
+
export * from '../plugin/PluginController';
|
|
3
|
+
export * from '../plugin/RimoriClient';
|
|
4
|
+
export * from '../utils/difficultyConverter';
|
|
5
|
+
export * from '../utils/Language';
|
|
6
|
+
export * from '../utils/PluginUtils';
|
|
7
|
+
export * from '../worker/WorkerSetup';
|
|
8
|
+
export { EventBusMessage } from '../fromRimori/EventBus';
|
|
9
|
+
export { Buddy, UserInfo } from './controller/SettingsController';
|
|
10
|
+
export { SharedContent } from './controller/SharedContentController';
|
|
11
|
+
export { Exercise, TriggerAction } from './controller/ExerciseController';
|
|
12
|
+
export { Message, OnLLMResponse, ToolInvocation } from './controller/AIController';
|
|
13
|
+
export { MacroAccomplishmentPayload, MicroAccomplishmentPayload } from '../plugin/AccomplishmentHandler';
|
|
14
|
+
export { Tool } from '../fromRimori/PluginTypes';
|
|
15
|
+
export { SharedContentObjectRequest } from './controller/SharedContentController';
|
package/dist/core/core.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Core functionality exports
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
2
|
+
export * from '../fromRimori/PluginTypes';
|
|
3
|
+
export * from '../plugin/PluginController';
|
|
4
|
+
export * from '../plugin/RimoriClient';
|
|
5
|
+
export * from '../utils/difficultyConverter';
|
|
6
|
+
export * from '../utils/Language';
|
|
7
|
+
export * from '../utils/PluginUtils';
|
|
8
|
+
export * from '../worker/WorkerSetup';
|
|
@@ -12,18 +12,18 @@ export class EventBusHandler {
|
|
|
12
12
|
this.listeners = new Map();
|
|
13
13
|
this.responseResolvers = new Map();
|
|
14
14
|
this.debugEnabled = false;
|
|
15
|
-
this.evName =
|
|
15
|
+
this.evName = '';
|
|
16
16
|
//private constructor
|
|
17
17
|
}
|
|
18
18
|
static getInstance(name) {
|
|
19
19
|
if (!EventBusHandler.instance) {
|
|
20
20
|
EventBusHandler.instance = new EventBusHandler();
|
|
21
|
-
EventBusHandler.instance.on(
|
|
21
|
+
EventBusHandler.instance.on('global.system.requestDebug', () => {
|
|
22
22
|
EventBusHandler.instance.debugEnabled = true;
|
|
23
23
|
console.log(`[${EventBusHandler.instance.evName}] Debug mode enabled. Make sure debugging messages are enabled in the browser console.`);
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
|
-
if (name && EventBusHandler.instance.evName ===
|
|
26
|
+
if (name && EventBusHandler.instance.evName === '') {
|
|
27
27
|
EventBusHandler.instance.evName = name;
|
|
28
28
|
}
|
|
29
29
|
return EventBusHandler.instance;
|
|
@@ -67,7 +67,7 @@ export class EventBusHandler {
|
|
|
67
67
|
}
|
|
68
68
|
const event = this.createEvent(sender, topic, data, eventId);
|
|
69
69
|
const handlers = this.getMatchingHandlers(event.topic);
|
|
70
|
-
handlers.forEach(handler => {
|
|
70
|
+
handlers.forEach((handler) => {
|
|
71
71
|
if (handler.ignoreSender && handler.ignoreSender.includes(sender)) {
|
|
72
72
|
// console.log("ignore event as its in the ignoreSender list", { event, ignoreList: handler.ignoreSender });
|
|
73
73
|
return;
|
|
@@ -93,7 +93,7 @@ export class EventBusHandler {
|
|
|
93
93
|
* @returns An EventListener object containing an off() method to unsubscribe the listeners.
|
|
94
94
|
*/
|
|
95
95
|
on(topics, handler, ignoreSender = []) {
|
|
96
|
-
const ids = this.toArray(topics).map(topic => {
|
|
96
|
+
const ids = this.toArray(topics).map((topic) => {
|
|
97
97
|
this.logIfDebug(`Subscribing to ` + topic, { ignoreSender });
|
|
98
98
|
if (!this.validateTopic(topic)) {
|
|
99
99
|
this.logAndThrowError(true, `Invalid topic: ` + topic);
|
|
@@ -109,7 +109,7 @@ export class EventBusHandler {
|
|
|
109
109
|
return btoa(JSON.stringify({ topic, id }));
|
|
110
110
|
});
|
|
111
111
|
return {
|
|
112
|
-
off: () => this.off(ids)
|
|
112
|
+
off: () => this.off(ids),
|
|
113
113
|
};
|
|
114
114
|
}
|
|
115
115
|
/**
|
|
@@ -121,10 +121,10 @@ export class EventBusHandler {
|
|
|
121
121
|
*/
|
|
122
122
|
respond(sender, topic, handler) {
|
|
123
123
|
const topics = Array.isArray(topic) ? topic : [topic];
|
|
124
|
-
const listeners = topics.map(topic => {
|
|
124
|
+
const listeners = topics.map((topic) => {
|
|
125
125
|
const blackListedEventIds = [];
|
|
126
126
|
//To allow event communication inside the same plugin the sender needs to be ignored but the events still need to be checked for the same event just reaching the subscriber to prevent infinite loops
|
|
127
|
-
const finalIgnoreSender = !topic.startsWith(
|
|
127
|
+
const finalIgnoreSender = !topic.startsWith('self.') ? [sender] : [];
|
|
128
128
|
const listener = this.on(topic, (data) => __awaiter(this, void 0, void 0, function* () {
|
|
129
129
|
if (blackListedEventIds.includes(data.eventId)) {
|
|
130
130
|
// console.log("BLACKLISTED EVENT ID", data.eventId);
|
|
@@ -134,16 +134,16 @@ export class EventBusHandler {
|
|
|
134
134
|
if (blackListedEventIds.length > 20) {
|
|
135
135
|
blackListedEventIds.shift();
|
|
136
136
|
}
|
|
137
|
-
const response = typeof handler ===
|
|
137
|
+
const response = typeof handler === 'function' ? yield handler(data) : handler;
|
|
138
138
|
this.emit(sender, topic, response, data.eventId);
|
|
139
139
|
}), finalIgnoreSender);
|
|
140
|
-
this.logIfDebug(`Added respond listener ` + sender +
|
|
140
|
+
this.logIfDebug(`Added respond listener ` + sender + ' to topic ' + topic, { listener, sender });
|
|
141
141
|
return {
|
|
142
|
-
off: () => listener.off()
|
|
142
|
+
off: () => listener.off(),
|
|
143
143
|
};
|
|
144
144
|
});
|
|
145
145
|
return {
|
|
146
|
-
off: () => listeners.forEach(listener => listener.off())
|
|
146
|
+
off: () => listeners.forEach((listener) => listener.off()),
|
|
147
147
|
};
|
|
148
148
|
}
|
|
149
149
|
/**
|
|
@@ -169,10 +169,10 @@ export class EventBusHandler {
|
|
|
169
169
|
* @param listenerIds - The ids of the listeners to unsubscribe from.
|
|
170
170
|
*/
|
|
171
171
|
off(listenerIds) {
|
|
172
|
-
this.toArray(listenerIds).forEach(fullId => {
|
|
172
|
+
this.toArray(listenerIds).forEach((fullId) => {
|
|
173
173
|
const { topic, id } = JSON.parse(atob(fullId));
|
|
174
174
|
const listeners = this.listeners.get(topic) || new Set();
|
|
175
|
-
listeners.forEach(listener => {
|
|
175
|
+
listeners.forEach((listener) => {
|
|
176
176
|
if (listener.id === Number(id)) {
|
|
177
177
|
listeners.delete(listener);
|
|
178
178
|
this.logIfDebug(`Removed listener ` + fullId, { topic, listenerId: id });
|
|
@@ -197,7 +197,7 @@ export class EventBusHandler {
|
|
|
197
197
|
}
|
|
198
198
|
const event = this.createEvent(sender, topic, data || {});
|
|
199
199
|
this.logIfDebug(`Requesting data from ` + topic, { event });
|
|
200
|
-
return new Promise(resolve => {
|
|
200
|
+
return new Promise((resolve) => {
|
|
201
201
|
this.responseResolvers.set(event.eventId, (value) => resolve(value));
|
|
202
202
|
this.emitInternal(sender, topic, data || {}, event.eventId, true);
|
|
203
203
|
});
|
|
@@ -212,7 +212,7 @@ export class EventBusHandler {
|
|
|
212
212
|
const exact = this.listeners.get(topic) || new Set();
|
|
213
213
|
// Find wildcard matches
|
|
214
214
|
const wildcard = [...this.listeners.entries()]
|
|
215
|
-
.filter(([key]) => key.endsWith(
|
|
215
|
+
.filter(([key]) => key.endsWith('*') && topic.startsWith(key.slice(0, -1)))
|
|
216
216
|
.flatMap(([_, handlers]) => [...handlers]);
|
|
217
217
|
return new Set([...exact, ...wildcard]);
|
|
218
218
|
}
|
|
@@ -223,27 +223,27 @@ export class EventBusHandler {
|
|
|
223
223
|
*/
|
|
224
224
|
validateTopic(topic) {
|
|
225
225
|
// Split event type into parts
|
|
226
|
-
const parts = topic.split(
|
|
226
|
+
const parts = topic.split('.');
|
|
227
227
|
const [plugin, area, action] = parts;
|
|
228
228
|
if (parts.length !== 3) {
|
|
229
|
-
if (parts.length === 1 && plugin ===
|
|
229
|
+
if (parts.length === 1 && plugin === '*') {
|
|
230
230
|
return true;
|
|
231
231
|
}
|
|
232
|
-
if (parts.length === 2 && plugin !==
|
|
232
|
+
if (parts.length === 2 && plugin !== '*' && area === '*') {
|
|
233
233
|
return true;
|
|
234
234
|
}
|
|
235
235
|
this.logAndThrowError(false, `Event type must have 3 parts separated by dots. Received: ` + topic);
|
|
236
236
|
return false;
|
|
237
237
|
}
|
|
238
|
-
if (action ===
|
|
238
|
+
if (action === '*') {
|
|
239
239
|
return true;
|
|
240
240
|
}
|
|
241
241
|
// Validate action part
|
|
242
|
-
const validActions = [
|
|
243
|
-
if (validActions.some(a => action.startsWith(a))) {
|
|
242
|
+
const validActions = ['request', 'create', 'update', 'delete', 'trigger'];
|
|
243
|
+
if (validActions.some((a) => action.startsWith(a))) {
|
|
244
244
|
return true;
|
|
245
245
|
}
|
|
246
|
-
this.logAndThrowError(false, `Invalid event topic name. The action: ` + action +
|
|
246
|
+
this.logAndThrowError(false, `Invalid event topic name. The action: ` + action + '. Must be or start with one of: ' + validActions.join(', '));
|
|
247
247
|
return false;
|
|
248
248
|
}
|
|
249
249
|
logIfDebug(...args) {
|
|
@@ -3,7 +3,7 @@ export type Plugin<T extends {} = {}> = Omit<RimoriPluginConfig<T>, 'context_men
|
|
|
3
3
|
endpoint: string;
|
|
4
4
|
assetEndpoint: string;
|
|
5
5
|
context_menu_actions: MenuEntry[];
|
|
6
|
-
release_channel:
|
|
6
|
+
release_channel: 'alpha' | 'beta' | 'stable';
|
|
7
7
|
};
|
|
8
8
|
export type ActivePlugin = Plugin<{
|
|
9
9
|
active?: boolean;
|
|
@@ -14,7 +14,7 @@ export interface PluginPage {
|
|
|
14
14
|
url: string;
|
|
15
15
|
show: boolean;
|
|
16
16
|
description: string;
|
|
17
|
-
root:
|
|
17
|
+
root: 'vocabulary' | 'grammar' | 'reading' | 'listening' | 'watching' | 'writing' | 'speaking' | 'other' | 'community';
|
|
18
18
|
action?: {
|
|
19
19
|
key: string;
|
|
20
20
|
parameters: ObjectTool;
|
|
@@ -79,7 +79,7 @@ export interface RimoriPluginConfig<T extends {} = {}> {
|
|
|
79
79
|
/**
|
|
80
80
|
* Context menu actions that the plugin registers to appear in right-click menus throughout the application.
|
|
81
81
|
*/
|
|
82
|
-
context_menu_actions: Omit<MenuEntry,
|
|
82
|
+
context_menu_actions: Omit<MenuEntry, 'plugin_id'>[];
|
|
83
83
|
/**
|
|
84
84
|
* Documentation paths for different types of plugin documentation.
|
|
85
85
|
*/
|
|
@@ -107,7 +107,7 @@ export interface Tool {
|
|
|
107
107
|
parameters: {
|
|
108
108
|
name: string;
|
|
109
109
|
description: string;
|
|
110
|
-
type:
|
|
110
|
+
type: 'string' | 'number' | 'boolean';
|
|
111
111
|
}[];
|
|
112
112
|
execute?: (args: Record<string, any>) => Promise<unknown> | unknown | void;
|
|
113
113
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { Tool } from
|
|
3
|
-
import { Message } from
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Tool } from '../fromRimori/PluginTypes';
|
|
3
|
+
import { Message } from '../core/controller/AIController';
|
|
4
4
|
export declare function useChat(tools?: Tool[]): {
|
|
5
5
|
messages: Message[];
|
|
6
6
|
append: (appendMessages: Message[]) => void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { useRimori } from
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useRimori } from '../providers/PluginProvider';
|
|
3
3
|
export function useChat(tools) {
|
|
4
4
|
const [messages, setMessages] = React.useState([]);
|
|
5
5
|
const [isLoading, setIsLoading] = React.useState(false);
|
|
@@ -19,5 +19,11 @@ export function useChat(tools) {
|
|
|
19
19
|
}
|
|
20
20
|
}, tools);
|
|
21
21
|
};
|
|
22
|
-
return {
|
|
22
|
+
return {
|
|
23
|
+
messages,
|
|
24
|
+
append,
|
|
25
|
+
isLoading,
|
|
26
|
+
setMessages,
|
|
27
|
+
lastMessage: messages[messages.length - 1],
|
|
28
|
+
};
|
|
23
29
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export * from './components';
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
9
|
-
export * from
|
|
10
|
-
export { FirstMessages } from
|
|
11
|
-
export { AudioController } from
|
|
2
|
+
export * from './hooks/UseChatHook';
|
|
3
|
+
export * from './plugin/PluginController';
|
|
4
|
+
export * from './providers/PluginProvider';
|
|
5
|
+
export * from './cli/types/DatabaseTypes';
|
|
6
|
+
export * from './utils/difficultyConverter';
|
|
7
|
+
export * from './utils/PluginUtils';
|
|
8
|
+
export * from './utils/Language';
|
|
9
|
+
export * from './fromRimori/PluginTypes';
|
|
10
|
+
export { FirstMessages } from './components/ai/utils';
|
|
11
|
+
export { AudioController } from './plugin/AudioController';
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// Re-export everything
|
|
2
2
|
export * from './components';
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
9
|
-
export * from
|
|
10
|
-
export * from
|
|
11
|
-
export { AudioController } from
|
|
3
|
+
export * from './hooks/UseChatHook';
|
|
4
|
+
export * from './plugin/PluginController';
|
|
5
|
+
export * from './providers/PluginProvider';
|
|
6
|
+
export * from './cli/types/DatabaseTypes';
|
|
7
|
+
export * from './utils/difficultyConverter';
|
|
8
|
+
export * from './utils/PluginUtils';
|
|
9
|
+
export * from './utils/Language';
|
|
10
|
+
export * from './fromRimori/PluginTypes';
|
|
11
|
+
export { AudioController } from './plugin/AudioController';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { EventBusMessage } from
|
|
1
|
+
import { EventBusMessage } from '../fromRimori/EventBus';
|
|
2
2
|
export type AccomplishmentMessage = EventBusMessage<MicroAccomplishmentPayload>;
|
|
3
3
|
export declare const skillCategories: readonly ["reading", "listening", "speaking", "writing", "learning", "community"];
|
|
4
4
|
interface BaseAccomplishmentPayload {
|
|
5
|
-
type:
|
|
5
|
+
type: 'micro' | 'macro';
|
|
6
6
|
skillCategory: (typeof skillCategories)[number];
|
|
7
7
|
accomplishmentKeyword: string;
|
|
8
8
|
description: string;
|
|
@@ -13,10 +13,10 @@ interface BaseAccomplishmentPayload {
|
|
|
13
13
|
}[];
|
|
14
14
|
}
|
|
15
15
|
export interface MicroAccomplishmentPayload extends BaseAccomplishmentPayload {
|
|
16
|
-
type:
|
|
16
|
+
type: 'micro';
|
|
17
17
|
}
|
|
18
18
|
export interface MacroAccomplishmentPayload extends BaseAccomplishmentPayload {
|
|
19
|
-
type:
|
|
19
|
+
type: 'macro';
|
|
20
20
|
errorRatio: number;
|
|
21
21
|
durationMinutes: number;
|
|
22
22
|
}
|
|
@@ -24,7 +24,7 @@ export type AccomplishmentPayload = MicroAccomplishmentPayload | MacroAccomplish
|
|
|
24
24
|
export declare class AccomplishmentHandler {
|
|
25
25
|
private pluginId;
|
|
26
26
|
constructor(pluginId: string);
|
|
27
|
-
emitAccomplishment(payload: Omit<AccomplishmentPayload,
|
|
27
|
+
emitAccomplishment(payload: Omit<AccomplishmentPayload, 'type'>): void;
|
|
28
28
|
private validateAccomplishment;
|
|
29
29
|
private sanitizeAccomplishment;
|
|
30
30
|
private getDecoupledTopic;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { EventBus } from
|
|
2
|
-
export const skillCategories = [
|
|
1
|
+
import { EventBus } from '../fromRimori/EventBus';
|
|
2
|
+
export const skillCategories = ['reading', 'listening', 'speaking', 'writing', 'learning', 'community'];
|
|
3
3
|
export class AccomplishmentHandler {
|
|
4
4
|
constructor(pluginId) {
|
|
5
5
|
this.pluginId = pluginId;
|
|
6
6
|
}
|
|
7
7
|
emitAccomplishment(payload) {
|
|
8
|
-
const accomplishmentPayload = Object.assign(Object.assign({}, payload), { type:
|
|
8
|
+
const accomplishmentPayload = Object.assign(Object.assign({}, payload), { type: 'durationMinutes' in payload ? 'macro' : 'micro' });
|
|
9
9
|
this.validateAccomplishment(accomplishmentPayload);
|
|
10
10
|
const sanitizedPayload = this.sanitizeAccomplishment(accomplishmentPayload);
|
|
11
|
-
const topic =
|
|
11
|
+
const topic = 'global.accomplishment.trigger' + (accomplishmentPayload.type === 'macro' ? 'Macro' : 'Micro');
|
|
12
12
|
EventBus.emit(this.pluginId, topic, sanitizedPayload);
|
|
13
13
|
}
|
|
14
14
|
validateAccomplishment(payload) {
|
|
@@ -21,68 +21,72 @@ export class AccomplishmentHandler {
|
|
|
21
21
|
}
|
|
22
22
|
//description is required
|
|
23
23
|
if (payload.description.length < 10) {
|
|
24
|
-
throw new Error(
|
|
24
|
+
throw new Error('Description is too short');
|
|
25
25
|
}
|
|
26
26
|
//check that the type is valid
|
|
27
|
-
if (![
|
|
28
|
-
throw new Error(
|
|
27
|
+
if (!['micro', 'macro'].includes(payload.type)) {
|
|
28
|
+
throw new Error('Invalid accomplishment type ' + payload.type);
|
|
29
29
|
}
|
|
30
30
|
//durationMinutes is required
|
|
31
|
-
if (payload.type ===
|
|
32
|
-
throw new Error(
|
|
31
|
+
if (payload.type === 'macro' && payload.durationMinutes < 4) {
|
|
32
|
+
throw new Error('The duration must be at least 4 minutes');
|
|
33
33
|
}
|
|
34
34
|
//errorRatio is required
|
|
35
|
-
if (payload.type ===
|
|
36
|
-
throw new Error(
|
|
35
|
+
if (payload.type === 'macro' && (payload.errorRatio < 0 || payload.errorRatio > 1)) {
|
|
36
|
+
throw new Error('The error ratio must be between 0 and 1');
|
|
37
37
|
}
|
|
38
38
|
//regex check meta data key
|
|
39
39
|
if (payload.meta) {
|
|
40
|
-
payload.meta.forEach(meta => {
|
|
40
|
+
payload.meta.forEach((meta) => {
|
|
41
41
|
if (!/^[a-z_]+$/.test(meta.key)) {
|
|
42
|
-
throw new Error(
|
|
42
|
+
throw new Error('Invalid meta data key ' + meta.key + ', only lowercase letters and underscores are allowed');
|
|
43
43
|
}
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
sanitizeAccomplishment(payload) {
|
|
48
48
|
var _a;
|
|
49
|
-
payload.description = payload.description.replace(/[^\x20-\x7E]/g,
|
|
49
|
+
payload.description = payload.description.replace(/[^\x20-\x7E]/g, '');
|
|
50
50
|
(_a = payload.meta) === null || _a === void 0 ? void 0 : _a.forEach((meta) => {
|
|
51
|
-
meta.description = meta.description.replace(/[^\x20-\x7E]/g,
|
|
51
|
+
meta.description = meta.description.replace(/[^\x20-\x7E]/g, '');
|
|
52
52
|
});
|
|
53
53
|
return payload;
|
|
54
54
|
}
|
|
55
55
|
getDecoupledTopic(topic) {
|
|
56
|
-
const [plugin, skillCategory, accomplishmentKeyword] = topic.split(
|
|
57
|
-
return {
|
|
56
|
+
const [plugin, skillCategory, accomplishmentKeyword] = topic.split('.');
|
|
57
|
+
return {
|
|
58
|
+
plugin: plugin || '*',
|
|
59
|
+
skillCategory: skillCategory || '*',
|
|
60
|
+
accomplishmentKeyword: accomplishmentKeyword || '*',
|
|
61
|
+
};
|
|
58
62
|
}
|
|
59
63
|
/**
|
|
60
64
|
* Subscribe to accomplishment events
|
|
61
65
|
* @param accomplishmentTopic - The topic of the accomplishment event. The pattern can be any pattern of plugin.skillCategory.accomplishmentKeyword or an * as wildcard for any plugin, skill category or accomplishment keyword
|
|
62
66
|
* @param callback - The callback function to be called when the accomplishment event is triggered
|
|
63
67
|
*/
|
|
64
|
-
subscribe(accomplishmentTopics =
|
|
65
|
-
if (typeof accomplishmentTopics ===
|
|
68
|
+
subscribe(accomplishmentTopics = '*', callback) {
|
|
69
|
+
if (typeof accomplishmentTopics === 'string') {
|
|
66
70
|
accomplishmentTopics = [accomplishmentTopics];
|
|
67
71
|
}
|
|
68
72
|
accomplishmentTopics.forEach((accomplishmentTopic) => {
|
|
69
|
-
const topicLength = accomplishmentTopic.split(
|
|
73
|
+
const topicLength = accomplishmentTopic.split('.').length;
|
|
70
74
|
if (topicLength === 1) {
|
|
71
|
-
accomplishmentTopic +=
|
|
75
|
+
accomplishmentTopic += '.*.*';
|
|
72
76
|
}
|
|
73
77
|
else if (topicLength === 2) {
|
|
74
|
-
accomplishmentTopic +=
|
|
78
|
+
accomplishmentTopic += '.*';
|
|
75
79
|
}
|
|
76
80
|
else if (topicLength !== 3) {
|
|
77
|
-
throw new Error(
|
|
81
|
+
throw new Error('Invalid accomplishment topic pattern. The pattern must be plugin.skillCategory.accomplishmentKeyword or an * as wildcard for any plugin, skill category or accomplishment keyword');
|
|
78
82
|
}
|
|
79
|
-
EventBus.on([
|
|
83
|
+
EventBus.on(['global.accomplishment.triggerMicro', 'global.accomplishment.triggerMacro'], (event) => {
|
|
80
84
|
const { plugin, skillCategory, accomplishmentKeyword } = this.getDecoupledTopic(accomplishmentTopic);
|
|
81
|
-
if (plugin !==
|
|
85
|
+
if (plugin !== '*' && event.sender !== plugin)
|
|
82
86
|
return;
|
|
83
|
-
if (skillCategory !==
|
|
87
|
+
if (skillCategory !== '*' && event.data.skillCategory !== skillCategory)
|
|
84
88
|
return;
|
|
85
|
-
if (accomplishmentKeyword !==
|
|
89
|
+
if (accomplishmentKeyword !== '*' && event.data.accomplishmentKeyword !== accomplishmentKeyword)
|
|
86
90
|
return;
|
|
87
91
|
callback(event);
|
|
88
92
|
}, [this.pluginId]);
|
|
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { EventBus } from
|
|
10
|
+
import { EventBus } from '../fromRimori/EventBus';
|
|
11
11
|
/**
|
|
12
12
|
* AudioController is a class that provides methods to record audio. It is a wrapper around the Capacitor Voice Recorder plugin. For more information, see https://github.com/tchvu3/capacitor-voice-recorder.
|
|
13
13
|
*
|
|
@@ -29,7 +29,7 @@ export class AudioController {
|
|
|
29
29
|
*/
|
|
30
30
|
startRecording() {
|
|
31
31
|
return __awaiter(this, void 0, void 0, function* () {
|
|
32
|
-
EventBus.emit(this.pluginId,
|
|
32
|
+
EventBus.emit(this.pluginId, 'global.microphone.triggerStartRecording');
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
@@ -43,25 +43,25 @@ export class AudioController {
|
|
|
43
43
|
*/
|
|
44
44
|
stopRecording() {
|
|
45
45
|
return __awaiter(this, void 0, void 0, function* () {
|
|
46
|
-
const result = yield EventBus.request(this.pluginId,
|
|
46
|
+
const result = yield EventBus.request(this.pluginId, 'global.microphone.triggerStopRecording');
|
|
47
47
|
return result.data;
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
50
|
pauseRecording() {
|
|
51
51
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52
|
-
const result = yield EventBus.request(this.pluginId,
|
|
52
|
+
const result = yield EventBus.request(this.pluginId, 'global.microphone.triggerPauseRecording');
|
|
53
53
|
return result.data;
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
56
|
resumeRecording() {
|
|
57
57
|
return __awaiter(this, void 0, void 0, function* () {
|
|
58
|
-
const result = yield EventBus.request(this.pluginId,
|
|
58
|
+
const result = yield EventBus.request(this.pluginId, 'global.microphone.triggerResumeRecording');
|
|
59
59
|
return result.data;
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
getCurrentStatus() {
|
|
63
63
|
return __awaiter(this, void 0, void 0, function* () {
|
|
64
|
-
const result = yield EventBus.request(this.pluginId,
|
|
64
|
+
const result = yield EventBus.request(this.pluginId, 'global.microphone.triggerGetCurrentStatus');
|
|
65
65
|
return result.data;
|
|
66
66
|
});
|
|
67
67
|
}
|
package/dist/plugin/Logger.js
CHANGED
|
@@ -25,7 +25,7 @@ export class Logger {
|
|
|
25
25
|
info: console.info,
|
|
26
26
|
warn: console.warn,
|
|
27
27
|
error: console.error,
|
|
28
|
-
debug: console.debug
|
|
28
|
+
debug: console.debug,
|
|
29
29
|
};
|
|
30
30
|
// Override console methods globally
|
|
31
31
|
this.overrideConsoleMethods();
|
|
@@ -40,7 +40,7 @@ export class Logger {
|
|
|
40
40
|
const logs = {
|
|
41
41
|
logs: this.logs,
|
|
42
42
|
pluginId: rimori.plugin.pluginId,
|
|
43
|
-
timestamp: new Date().toISOString()
|
|
43
|
+
timestamp: new Date().toISOString(),
|
|
44
44
|
};
|
|
45
45
|
this.logs = [];
|
|
46
46
|
this.logIdCounter = 0;
|
|
@@ -84,7 +84,7 @@ export class Logger {
|
|
|
84
84
|
if (typeof window === 'undefined' || typeof history === 'undefined')
|
|
85
85
|
return;
|
|
86
86
|
// Clear logs on browser back/forward
|
|
87
|
-
window.addEventListener('popstate', () => this.logs = []);
|
|
87
|
+
window.addEventListener('popstate', () => (this.logs = []));
|
|
88
88
|
// Override history methods to clear logs on programmatic navigation
|
|
89
89
|
const originalPushState = history.pushState;
|
|
90
90
|
const originalReplaceState = history.replaceState;
|
|
@@ -107,7 +107,7 @@ export class Logger {
|
|
|
107
107
|
// Check for URL changes periodically
|
|
108
108
|
setInterval(checkUrlChange, 100);
|
|
109
109
|
// Also listen for hash changes (for hash-based routing)
|
|
110
|
-
window.addEventListener('hashchange', () => this.logs = []);
|
|
110
|
+
window.addEventListener('hashchange', () => (this.logs = []));
|
|
111
111
|
}
|
|
112
112
|
/**
|
|
113
113
|
* Override console methods globally to capture all console calls.
|
|
@@ -149,8 +149,8 @@ export class Logger {
|
|
|
149
149
|
* @returns Object with location string and CSS style, or empty values for production
|
|
150
150
|
*/
|
|
151
151
|
getCallerLocation() {
|
|
152
|
-
const emptyResult = { location:
|
|
153
|
-
const style =
|
|
152
|
+
const emptyResult = { location: '', style: '' };
|
|
153
|
+
const style = 'color: #0063A2; font-weight: bold;';
|
|
154
154
|
if (this.isProduction)
|
|
155
155
|
return emptyResult;
|
|
156
156
|
try {
|
|
@@ -189,7 +189,7 @@ export class Logger {
|
|
|
189
189
|
this.mousePosition = {
|
|
190
190
|
x: event.clientX,
|
|
191
191
|
y: event.clientY,
|
|
192
|
-
timestamp: new Date().toISOString()
|
|
192
|
+
timestamp: new Date().toISOString(),
|
|
193
193
|
};
|
|
194
194
|
};
|
|
195
195
|
window.addEventListener('mousemove', updateMousePosition);
|
|
@@ -208,16 +208,18 @@ export class Logger {
|
|
|
208
208
|
return;
|
|
209
209
|
}
|
|
210
210
|
// Convert console arguments to message and data
|
|
211
|
-
const message = args
|
|
212
|
-
|
|
211
|
+
const message = args
|
|
212
|
+
.map((arg) => {
|
|
213
|
+
if (typeof arg !== 'object')
|
|
213
214
|
return arg;
|
|
214
215
|
try {
|
|
215
216
|
return JSON.stringify(arg);
|
|
216
217
|
}
|
|
217
218
|
catch (error) {
|
|
218
|
-
return
|
|
219
|
+
return 'Error adding object to log: ' + error.message + ' ' + String(arg);
|
|
219
220
|
}
|
|
220
|
-
})
|
|
221
|
+
})
|
|
222
|
+
.join(' ');
|
|
221
223
|
const data = args.length > 1 ? args.slice(1) : undefined;
|
|
222
224
|
const entry = yield this.createLogEntry(level, message, data);
|
|
223
225
|
this.addLogEntry(entry);
|
|
@@ -235,7 +237,7 @@ export class Logger {
|
|
|
235
237
|
onLine: navigator.onLine,
|
|
236
238
|
screenResolution: `${screen.width}x${screen.height}`,
|
|
237
239
|
windowSize: `${window.innerWidth}x${window.innerHeight}`,
|
|
238
|
-
timestamp: new Date().toISOString()
|
|
240
|
+
timestamp: new Date().toISOString(),
|
|
239
241
|
};
|
|
240
242
|
}
|
|
241
243
|
/**
|
|
@@ -288,7 +290,7 @@ export class Logger {
|
|
|
288
290
|
level,
|
|
289
291
|
message,
|
|
290
292
|
data,
|
|
291
|
-
context: context
|
|
293
|
+
context: context,
|
|
292
294
|
};
|
|
293
295
|
});
|
|
294
296
|
}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
2
2
|
import { UserInfo } from '../core/controller/SettingsController';
|
|
3
3
|
import { ActivePlugin, Plugin } from '../fromRimori/PluginTypes';
|
|
4
|
-
import { RimoriClient } from
|
|
4
|
+
import { RimoriClient } from './RimoriClient';
|
|
5
|
+
export interface Guild {
|
|
6
|
+
id: string;
|
|
7
|
+
longTermGoalOverride: string;
|
|
8
|
+
allowUserPluginSettings: boolean;
|
|
9
|
+
}
|
|
5
10
|
export interface RimoriInfo {
|
|
6
11
|
url: string;
|
|
7
12
|
key: string;
|
|
@@ -10,6 +15,7 @@ export interface RimoriInfo {
|
|
|
10
15
|
expiration: Date;
|
|
11
16
|
tablePrefix: string;
|
|
12
17
|
pluginId: string;
|
|
18
|
+
guild: Guild;
|
|
13
19
|
installedPlugins: Plugin[];
|
|
14
20
|
profile: UserInfo;
|
|
15
21
|
mainPanelPlugin?: ActivePlugin;
|