@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.
- package/README.md +51 -0
- package/dist/components/CRUDModal.js +0 -1
- package/dist/components/ai/Assistant.d.ts +9 -0
- package/dist/components/ai/Assistant.js +59 -0
- package/dist/components/ai/Avatar.d.ts +11 -0
- package/dist/components/ai/Avatar.js +39 -0
- package/dist/components/ai/EmbeddedAssistent/AudioInputField.d.ts +7 -0
- package/dist/components/ai/EmbeddedAssistent/AudioInputField.js +38 -0
- package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.d.ts +7 -0
- package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.js +59 -0
- package/dist/components/ai/EmbeddedAssistent/TTS/MessageSender.d.ts +19 -0
- package/dist/components/ai/EmbeddedAssistent/TTS/MessageSender.js +86 -0
- package/dist/components/ai/EmbeddedAssistent/TTS/Player.d.ts +25 -0
- package/dist/components/ai/EmbeddedAssistent/TTS/Player.js +180 -0
- package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.d.ts +7 -0
- package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.js +45 -0
- package/dist/components/ai/utils.d.ts +6 -0
- package/dist/components/ai/utils.js +14 -0
- package/dist/components/audio/Playbutton.js +4 -5
- package/dist/components/avatar/Assistant.d.ts +9 -0
- package/dist/components/avatar/Assistant.js +59 -0
- package/dist/components/avatar/Avatar.d.ts +12 -0
- package/dist/components/avatar/Avatar.js +42 -0
- package/dist/components/avatar/EmbeddedAssistent/AudioInputField.d.ts +7 -0
- package/dist/components/avatar/EmbeddedAssistent/AudioInputField.js +38 -0
- package/dist/components/avatar/EmbeddedAssistent/CircleAudioAvatar.d.ts +7 -0
- package/dist/components/avatar/EmbeddedAssistent/CircleAudioAvatar.js +59 -0
- package/dist/components/avatar/EmbeddedAssistent/TTS/MessageSender.d.ts +19 -0
- package/dist/components/avatar/EmbeddedAssistent/TTS/MessageSender.js +84 -0
- package/dist/components/avatar/EmbeddedAssistent/TTS/Player.d.ts +25 -0
- package/dist/components/avatar/EmbeddedAssistent/TTS/Player.js +180 -0
- package/dist/components/avatar/EmbeddedAssistent/VoiceRecoder.d.ts +7 -0
- package/dist/components/avatar/EmbeddedAssistent/VoiceRecoder.js +45 -0
- package/dist/components/avatar/utils.d.ts +6 -0
- package/dist/components/avatar/utils.js +14 -0
- package/dist/components.d.ts +9 -0
- package/dist/components.js +10 -0
- package/dist/controller/AIController.d.ts +4 -3
- package/dist/controller/AIController.js +32 -8
- package/dist/controller/ObjectController.d.ts +2 -2
- package/dist/controller/ObjectController.js +4 -5
- package/dist/controller/SettingsController.d.ts +19 -10
- package/dist/controller/SettingsController.js +33 -26
- package/dist/controller/SharedContentController.js +6 -6
- package/dist/core.d.ts +9 -0
- package/dist/core.js +10 -0
- package/dist/hooks/UseChatHook.js +2 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +4 -2
- package/dist/plugin/PluginController.d.ts +4 -12
- package/dist/plugin/PluginController.js +45 -70
- package/dist/plugin/RimoriClient.d.ts +85 -32
- package/dist/plugin/RimoriClient.js +98 -77
- package/dist/plugin/ThemeSetter.js +3 -3
- package/dist/plugin/fromRimori/EventBus.d.ts +98 -0
- package/dist/plugin/fromRimori/EventBus.js +240 -0
- package/dist/providers/PluginProvider.d.ts +1 -0
- package/dist/providers/PluginProvider.js +10 -12
- package/dist/worker/WorkerSetup.d.ts +6 -0
- package/dist/worker/WorkerSetup.js +80 -0
- package/package.json +17 -3
- package/src/components/CRUDModal.tsx +1 -3
- package/src/components/ai/Assistant.tsx +96 -0
- package/src/components/ai/Avatar.tsx +61 -0
- package/src/components/ai/EmbeddedAssistent/AudioInputField.tsx +64 -0
- package/src/components/ai/EmbeddedAssistent/CircleAudioAvatar.tsx +75 -0
- package/src/components/ai/EmbeddedAssistent/TTS/MessageSender.ts +91 -0
- package/src/components/ai/EmbeddedAssistent/TTS/Player.ts +192 -0
- package/src/components/ai/EmbeddedAssistent/VoiceRecoder.tsx +56 -0
- package/src/components/ai/utils.ts +23 -0
- package/src/components/audio/Playbutton.tsx +4 -5
- package/src/components.ts +10 -0
- package/src/controller/AIController.ts +84 -60
- package/src/controller/ObjectController.ts +4 -6
- package/src/controller/SettingsController.ts +49 -35
- package/src/controller/SharedContentController.ts +6 -6
- package/src/core.ts +10 -0
- package/src/hooks/UseChatHook.ts +2 -2
- package/src/index.ts +4 -2
- package/src/plugin/PluginController.ts +51 -76
- package/src/plugin/RimoriClient.ts +147 -85
- package/src/plugin/ThemeSetter.ts +3 -4
- package/src/plugin/fromRimori/EventBus.ts +301 -0
- package/src/plugin/fromRimori/readme.md +2 -0
- package/src/providers/PluginProvider.tsx +12 -14
- package/src/worker/WorkerSetup.ts +81 -0
- package/dist/CRUDModal.d.ts +0 -16
- package/dist/CRUDModal.js +0 -31
- package/dist/MarkdownEditor.d.ts +0 -8
- package/dist/MarkdownEditor.js +0 -46
- package/dist/audio/Playbutton.d.ts +0 -14
- package/dist/audio/Playbutton.js +0 -73
- package/dist/components/hooks/UseChatHook.d.ts +0 -15
- package/dist/components/hooks/UseChatHook.js +0 -21
- package/dist/controller/PluginController.d.ts +0 -14
- package/dist/controller/PluginController.js +0 -30
- package/dist/plugin/AIController copy.d.ts +0 -22
- package/dist/plugin/AIController copy.js +0 -68
- package/dist/plugin/AIController.d.ts +0 -22
- package/dist/plugin/AIController.js +0 -68
- package/dist/plugin/ObjectController.d.ts +0 -34
- package/dist/plugin/ObjectController.js +0 -77
- package/dist/plugin/SettingController.d.ts +0 -13
- package/dist/plugin/SettingController.js +0 -55
- package/dist/plugin/VoiceController.d.ts +0 -2
- package/dist/plugin/VoiceController.js +0 -27
- package/dist/providers/EventEmitter.d.ts +0 -11
- package/dist/providers/EventEmitter.js +0 -41
- package/dist/providers/EventEmitterContext.d.ts +0 -6
- package/dist/providers/EventEmitterContext.js +0 -19
- package/dist/utils/DifficultyConverter.d.ts +0 -3
- package/dist/utils/DifficultyConverter.js +0 -7
- package/dist/utils/constants.d.ts +0 -4
- package/dist/utils/constants.js +0 -12
- package/dist/utils/plugin/Client.d.ts +0 -72
- package/dist/utils/plugin/Client.js +0 -118
- package/dist/utils/plugin/PluginController.d.ts +0 -36
- package/dist/utils/plugin/PluginController.js +0 -119
- package/dist/utils/plugin/PluginUtils.d.ts +0 -2
- package/dist/utils/plugin/PluginUtils.js +0 -23
- package/dist/utils/plugin/RimoriClient.d.ts +0 -72
- package/dist/utils/plugin/RimoriClient.js +0 -118
- package/dist/utils/plugin/ThemeSetter.d.ts +0 -1
- package/dist/utils/plugin/ThemeSetter.js +0 -13
- package/dist/utils/plugin/WhereClauseBuilder.d.ts +0 -24
- package/dist/utils/plugin/WhereClauseBuilder.js +0 -79
- package/dist/utils/plugin/providers/EventEmitter.d.ts +0 -11
- package/dist/utils/plugin/providers/EventEmitter.js +0 -41
- package/dist/utils/plugin/providers/EventEmitterContext.d.ts +0 -6
- package/dist/utils/plugin/providers/EventEmitterContext.js +0 -19
- package/dist/utils/plugin/providers/PluginProvider.d.ts +0 -8
- package/dist/utils/plugin/providers/PluginProvider.js +0 -49
- package/src/providers/EventEmitter.ts +0 -48
- package/src/providers/EventEmitterContext.tsx +0 -27
- package/src/utils/constants.ts +0 -18
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PluginController } from "./PluginController";
|
|
2
2
|
import { SupabaseClient } from "@supabase/supabase-js";
|
|
3
|
+
import { EventBusMessage, EventPayload } from "./fromRimori/EventBus";
|
|
3
4
|
import { SettingsController } from "../controller/SettingsController";
|
|
4
5
|
import { GenericSchema } from "@supabase/supabase-js/dist/module/lib/types";
|
|
5
6
|
import { getSTTResponse, getTTSResponse } from "../controller/VoiceController";
|
|
@@ -8,6 +9,8 @@ import { SharedContentController, BasicAssignment } from "../controller/SharedCo
|
|
|
8
9
|
import { streamChatGPT, Message, Tool, OnLLMResponse, generateText } from "../controller/AIController";
|
|
9
10
|
import { generateObject as generateObjectFunction, ObjectRequest } from "../controller/ObjectController";
|
|
10
11
|
import { getPlugins, Plugin } from "../controller/SidePluginController";
|
|
12
|
+
import { UserInfo } from "../controller/SettingsController";
|
|
13
|
+
import { EventBus, EventHandler } from "./fromRimori/EventBus";
|
|
11
14
|
|
|
12
15
|
interface RimoriClientOptions {
|
|
13
16
|
pluginController: PluginController;
|
|
@@ -16,38 +19,132 @@ interface RimoriClientOptions {
|
|
|
16
19
|
pluginId: string;
|
|
17
20
|
}
|
|
18
21
|
|
|
22
|
+
interface Db {
|
|
23
|
+
from: {
|
|
24
|
+
<TableName extends string & keyof GenericSchema['Tables'], Table extends GenericSchema['Tables'][TableName]>(relation: TableName): PostgrestQueryBuilder<GenericSchema, Table, TableName>;
|
|
25
|
+
<ViewName extends string & keyof GenericSchema['Views'], View extends GenericSchema['Views'][ViewName]>(relation: ViewName): PostgrestQueryBuilder<GenericSchema, View, ViewName>;
|
|
26
|
+
};
|
|
27
|
+
rpc: <Fn extends GenericSchema['Functions'][string], FnName extends string & keyof GenericSchema['Functions']>(functionName: FnName, args?: Fn["Args"], options?: {
|
|
28
|
+
head?: boolean;
|
|
29
|
+
get?: boolean;
|
|
30
|
+
count?: "exact" | "planned" | "estimated";
|
|
31
|
+
}) => PostgrestFilterBuilder<GenericSchema, Fn["Returns"] extends any[] ? Fn["Returns"][number] extends Record<string, unknown> ? Fn["Returns"][number] : never : never, Fn["Returns"], string, null>;
|
|
32
|
+
functions: SupabaseClient["functions"];
|
|
33
|
+
storage: SupabaseClient["storage"];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface PluginInterface {
|
|
37
|
+
pluginId: string;
|
|
38
|
+
tablePrefix: string;
|
|
39
|
+
setSettings: (settings: any) => Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Get the settings for the plugin. T can be any type of settings, UserSettings or SystemSettings.
|
|
42
|
+
* @param defaultSettings The default settings to use if no settings are found.
|
|
43
|
+
* @param genericSettings The type of settings to get.
|
|
44
|
+
* @returns The settings for the plugin.
|
|
45
|
+
*/
|
|
46
|
+
getSettings: <T extends object>(defaultSettings: T) => Promise<T>;
|
|
47
|
+
/**
|
|
48
|
+
* Fetches all installed plugins.
|
|
49
|
+
* @returns A promise that resolves to an array of plugins
|
|
50
|
+
*/
|
|
51
|
+
getInstalled: () => Promise<Plugin[]>;
|
|
52
|
+
getUserInfo: () => Promise<UserInfo>;
|
|
53
|
+
}
|
|
54
|
+
|
|
19
55
|
export class RimoriClient {
|
|
20
56
|
private static instance: RimoriClient;
|
|
21
57
|
private superbase: SupabaseClient;
|
|
22
|
-
private
|
|
23
|
-
public functions: SupabaseClient["functions"];
|
|
24
|
-
public storage: SupabaseClient["storage"];
|
|
25
|
-
public pluginId: string;
|
|
26
|
-
public tablePrefix: string;
|
|
58
|
+
private pluginController: PluginController;
|
|
27
59
|
private settingsController: SettingsController;
|
|
28
60
|
private sharedContentController: SharedContentController;
|
|
61
|
+
private supabaseUrl: string;
|
|
62
|
+
public db: Db;
|
|
63
|
+
public plugin: PluginInterface;
|
|
29
64
|
|
|
30
65
|
private constructor(options: RimoriClientOptions) {
|
|
31
66
|
this.superbase = options.supabase;
|
|
32
|
-
this.
|
|
33
|
-
this.plugin = options.pluginController;
|
|
34
|
-
this.tablePrefix = options.tablePrefix;
|
|
35
|
-
this.storage = this.superbase.storage;
|
|
36
|
-
this.functions = this.superbase.functions;
|
|
67
|
+
this.pluginController = options.pluginController;
|
|
37
68
|
this.settingsController = new SettingsController(options.supabase, options.pluginId);
|
|
38
69
|
this.sharedContentController = new SharedContentController(this);
|
|
70
|
+
this.supabaseUrl = this.pluginController.getSupabaseUrl();
|
|
71
|
+
|
|
39
72
|
this.rpc = this.rpc.bind(this);
|
|
40
73
|
this.from = this.from.bind(this);
|
|
41
|
-
|
|
42
|
-
this.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
this.
|
|
49
|
-
|
|
50
|
-
|
|
74
|
+
|
|
75
|
+
this.db = {
|
|
76
|
+
rpc: this.rpc,
|
|
77
|
+
from: this.from,
|
|
78
|
+
storage: this.superbase.storage,
|
|
79
|
+
functions: this.superbase.functions,
|
|
80
|
+
}
|
|
81
|
+
this.plugin = {
|
|
82
|
+
pluginId: options.pluginId,
|
|
83
|
+
tablePrefix: options.tablePrefix,
|
|
84
|
+
setSettings: async (settings: any) => {
|
|
85
|
+
await this.settingsController.setSettings(settings);
|
|
86
|
+
},
|
|
87
|
+
getSettings: async <T extends object>(defaultSettings: T): Promise<T> => {
|
|
88
|
+
return await this.settingsController.getSettings<T>(defaultSettings);
|
|
89
|
+
},
|
|
90
|
+
getInstalled: async (): Promise<Plugin[]> => {
|
|
91
|
+
return getPlugins(this.superbase);
|
|
92
|
+
},
|
|
93
|
+
getUserInfo: async (): Promise<UserInfo> => {
|
|
94
|
+
return this.settingsController.getUserInfo();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
public event = {
|
|
100
|
+
/**
|
|
101
|
+
* Emit an event to Rimori or a plugin.
|
|
102
|
+
* The topic schema is:
|
|
103
|
+
* {pluginId}.{eventId}
|
|
104
|
+
* Check out the event bus documentation for more information.
|
|
105
|
+
* For triggering events from Rimori like context menu actions use the "global" keyword.
|
|
106
|
+
* @param topic The topic to emit the event on.
|
|
107
|
+
* @param data The data to emit.
|
|
108
|
+
* @param eventId The event id.
|
|
109
|
+
*/
|
|
110
|
+
emit: (topic: string, data: any, eventId?: number) => {
|
|
111
|
+
const globalTopic = this.pluginController.getGlobalEventTopic(topic);
|
|
112
|
+
EventBus.emit(this.plugin.pluginId, globalTopic, data, eventId);
|
|
113
|
+
},
|
|
114
|
+
/**
|
|
115
|
+
* Request an event.
|
|
116
|
+
* @param topic The topic to request the event on.
|
|
117
|
+
* @param data The data to request.
|
|
118
|
+
* @returns The response from the event.
|
|
119
|
+
*/
|
|
120
|
+
request: <T>(topic: string, data?: any): Promise<EventBusMessage<T>> => {
|
|
121
|
+
const globalTopic = this.pluginController.getGlobalEventTopic(topic);
|
|
122
|
+
return EventBus.request<T>(this.plugin.pluginId, globalTopic, data);
|
|
123
|
+
},
|
|
124
|
+
/**
|
|
125
|
+
* Subscribe to an event.
|
|
126
|
+
* @param topic The topic to subscribe to.
|
|
127
|
+
* @param callback The callback to call when the event is emitted.
|
|
128
|
+
*/
|
|
129
|
+
on: <T = EventPayload>(topic: string, callback: EventHandler<T>) => {
|
|
130
|
+
EventBus.on<T>(this.pluginController.getGlobalEventTopic(topic), callback);
|
|
131
|
+
},
|
|
132
|
+
/**
|
|
133
|
+
* Subscribe to an event once.
|
|
134
|
+
* @param topic The topic to subscribe to.
|
|
135
|
+
* @param callback The callback to call when the event is emitted.
|
|
136
|
+
*/
|
|
137
|
+
once: <T = EventPayload>(topic: string, callback: EventHandler<T>) => {
|
|
138
|
+
EventBus.once<T>(this.pluginController.getGlobalEventTopic(topic), callback);
|
|
139
|
+
},
|
|
140
|
+
/**
|
|
141
|
+
* Respond to an event.
|
|
142
|
+
* @param topic The topic to respond to.
|
|
143
|
+
* @param data The data to respond with.
|
|
144
|
+
*/
|
|
145
|
+
respond: <T = EventPayload>(topic: string, data: EventPayload | ((data: EventBusMessage<T>) => EventPayload | Promise<EventPayload>)) => {
|
|
146
|
+
EventBus.respond(this.plugin.pluginId, this.pluginController.getGlobalEventTopic(topic), data);
|
|
147
|
+
}
|
|
51
148
|
}
|
|
52
149
|
|
|
53
150
|
public static async getInstance(pluginController: PluginController): Promise<RimoriClient> {
|
|
@@ -58,15 +155,15 @@ export class RimoriClient {
|
|
|
58
155
|
return RimoriClient.instance;
|
|
59
156
|
}
|
|
60
157
|
|
|
61
|
-
|
|
158
|
+
private from<
|
|
62
159
|
TableName extends string & keyof GenericSchema['Tables'],
|
|
63
160
|
Table extends GenericSchema['Tables'][TableName]
|
|
64
161
|
>(relation: TableName): PostgrestQueryBuilder<GenericSchema, Table, TableName>
|
|
65
|
-
|
|
162
|
+
private from<
|
|
66
163
|
ViewName extends string & keyof GenericSchema['Views'],
|
|
67
164
|
View extends GenericSchema['Views'][ViewName]
|
|
68
165
|
>(relation: ViewName): PostgrestQueryBuilder<GenericSchema, View, ViewName>
|
|
69
|
-
|
|
166
|
+
private from(relation: string): PostgrestQueryBuilder<GenericSchema, any, any> {
|
|
70
167
|
return this.superbase.from(this.getTableName(relation));
|
|
71
168
|
}
|
|
72
169
|
|
|
@@ -93,7 +190,7 @@ export class RimoriClient {
|
|
|
93
190
|
* `"estimated"`: Uses exact count for low numbers and planned count for high
|
|
94
191
|
* numbers.
|
|
95
192
|
*/
|
|
96
|
-
rpc<Fn extends GenericSchema['Functions'][string], FnName extends string & keyof GenericSchema['Functions']>(
|
|
193
|
+
private rpc<Fn extends GenericSchema['Functions'][string], FnName extends string & keyof GenericSchema['Functions']>(
|
|
97
194
|
functionName: FnName,
|
|
98
195
|
args: Fn['Args'] = {},
|
|
99
196
|
options: {
|
|
@@ -116,68 +213,33 @@ export class RimoriClient {
|
|
|
116
213
|
}
|
|
117
214
|
|
|
118
215
|
private getTableName(type: string) {
|
|
119
|
-
return this.tablePrefix + "_" + type;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
public subscribe(eventName: string, callback: (_id: number, data: any) => void) {
|
|
123
|
-
this.plugin.subscribe(eventName, callback);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
public request<T>(eventName: string, data?: any): Promise<T> {
|
|
127
|
-
return this.plugin.request(eventName, data);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
public emit(eventName: string, data: any) {
|
|
131
|
-
this.plugin.emit(eventName, data);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Get the settings for the plugin. T can be any type of settings, UserSettings or SystemSettings.
|
|
136
|
-
* @param defaultSettings The default settings to use if no settings are found.
|
|
137
|
-
* @param genericSettings The type of settings to get.
|
|
138
|
-
* @returns The settings for the plugin.
|
|
139
|
-
*/
|
|
140
|
-
public async getSettings<T extends object>(defaultSettings: T, genericSettings?: "user" | "system"): Promise<T> {
|
|
141
|
-
return this.settingsController.getSettings<T>(defaultSettings, genericSettings);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
public async setSettings(settings: any, genericSettings?: "user" | "system") {
|
|
145
|
-
await this.settingsController.setSettings(settings, genericSettings);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
public async getAIResponse(messages: Message[], tools?: Tool[]): Promise<string> {
|
|
149
|
-
const token = await this.plugin.getToken();
|
|
150
|
-
return generateText(messages, tools || [], token).then(response => response.messages[0].content[0].text);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
public async getAIResponseStream(messages: Message[], onMessage: OnLLMResponse, tools?: Tool[]) {
|
|
154
|
-
const token = await this.plugin.getToken();
|
|
155
|
-
streamChatGPT(messages, tools || [], onMessage, token);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
public async getVoiceResponse(text: string, voice = "alloy", speed = 1, language?: string): Promise<Blob> {
|
|
159
|
-
return getTTSResponse(
|
|
160
|
-
this.plugin.getSupabaseUrl(),
|
|
161
|
-
{ input: text, voice, speed, language },
|
|
162
|
-
await this.plugin.getToken()
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
public getVoiceToTextResponse(file: Blob): Promise<string> {
|
|
167
|
-
return getSTTResponse(this.superbase, file);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Fetches all installed plugins.
|
|
172
|
-
* @returns A promise that resolves to an array of plugins
|
|
173
|
-
*/
|
|
174
|
-
public async getPlugins(): Promise<Plugin[]> {
|
|
175
|
-
return getPlugins(this.superbase);
|
|
216
|
+
return this.plugin.tablePrefix + "_" + type;
|
|
176
217
|
}
|
|
177
218
|
|
|
178
|
-
public
|
|
179
|
-
|
|
180
|
-
|
|
219
|
+
public llm = {
|
|
220
|
+
getText: async (messages: Message[], tools?: Tool[]): Promise<string> => {
|
|
221
|
+
const token = await this.pluginController.getToken();
|
|
222
|
+
return generateText(this.supabaseUrl, messages, tools || [], token).then(response => response.messages[0].content[0].text);
|
|
223
|
+
},
|
|
224
|
+
getSteamedText: async (messages: Message[], onMessage: OnLLMResponse, tools?: Tool[]) => {
|
|
225
|
+
const token = await this.pluginController.getToken();
|
|
226
|
+
streamChatGPT(this.supabaseUrl, messages, tools || [], onMessage, token);
|
|
227
|
+
},
|
|
228
|
+
getVoice: async (text: string, voice = "alloy", speed = 1, language?: string): Promise<Blob> => {
|
|
229
|
+
return getTTSResponse(
|
|
230
|
+
this.pluginController.getSupabaseUrl(),
|
|
231
|
+
{ input: text, voice, speed, language },
|
|
232
|
+
await this.pluginController.getToken()
|
|
233
|
+
);
|
|
234
|
+
},
|
|
235
|
+
getTextFromVoice: (file: Blob): Promise<string> => {
|
|
236
|
+
return getSTTResponse(this.superbase, file);
|
|
237
|
+
},
|
|
238
|
+
getObject: async (request: ObjectRequest): Promise<any> => {
|
|
239
|
+
const token = await this.pluginController.getToken();
|
|
240
|
+
return generateObjectFunction(this.pluginController.getSupabaseUrl(), request, token);
|
|
241
|
+
},
|
|
242
|
+
// getSteamedObject: this.generateObjectStream,
|
|
181
243
|
}
|
|
182
244
|
|
|
183
245
|
/**
|
|
@@ -215,6 +277,6 @@ export class RimoriClient {
|
|
|
215
277
|
}
|
|
216
278
|
|
|
217
279
|
public triggerSidebarAction(pluginId: string, actionKey: string, text?: string) {
|
|
218
|
-
this.emit("
|
|
280
|
+
this.event.emit("global.sidebar.triggerAction", { pluginId, actionKey, text });
|
|
219
281
|
}
|
|
220
282
|
}
|
|
@@ -2,8 +2,6 @@ export function setTheme() {
|
|
|
2
2
|
const urlParams = new URLSearchParams(window.location.search);
|
|
3
3
|
|
|
4
4
|
let theme = urlParams.get('theme');
|
|
5
|
-
const isSidebar = urlParams.get('applicationMode') === "sidebar";
|
|
6
|
-
|
|
7
5
|
if (!theme || theme === 'system') {
|
|
8
6
|
theme = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
9
7
|
}
|
|
@@ -11,7 +9,8 @@ export function setTheme() {
|
|
|
11
9
|
document.documentElement.classList.add("dark:text-gray-200", "bg-white");
|
|
12
10
|
|
|
13
11
|
if (theme === 'dark') {
|
|
14
|
-
document.documentElement.
|
|
15
|
-
document.documentElement.
|
|
12
|
+
document.documentElement.setAttribute("data-theme", "dark");
|
|
13
|
+
document.documentElement.classList.add('dark', "bg-gray-950");
|
|
14
|
+
document.documentElement.style.background = "hsl(var(--background))";
|
|
16
15
|
}
|
|
17
16
|
}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2
|
+
export type EventPayload = Record<string, any>;
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Interface representing a message sent through the EventBus
|
|
6
|
+
*
|
|
7
|
+
* Debug capabilities:
|
|
8
|
+
* - System-wide debugging: Send an event to "global.system.requestDebug"
|
|
9
|
+
* Example: `EventBus.emit("yourPluginId", "global.system.requestDebug");`
|
|
10
|
+
*/
|
|
11
|
+
export interface EventBusMessage<T = EventPayload> {
|
|
12
|
+
//timestamp of the event
|
|
13
|
+
timestamp: string;
|
|
14
|
+
//unique ID of the event
|
|
15
|
+
eventId: number;
|
|
16
|
+
//plugin id or "global" for global events
|
|
17
|
+
sender: string;
|
|
18
|
+
//the topic of the event consisting of the plugin id, key area and action e.g. "translator.word.triggerTranslation"
|
|
19
|
+
topic: string;
|
|
20
|
+
//any type of data to be transmitted
|
|
21
|
+
data: T;
|
|
22
|
+
//indicated if the debug mode is active
|
|
23
|
+
debug: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type EventHandler<T = EventPayload> = (event: EventBusMessage<T>) => void | Promise<void>;
|
|
27
|
+
|
|
28
|
+
interface Listeners<T = EventPayload> {
|
|
29
|
+
id: number;
|
|
30
|
+
handler: EventHandler<T>;
|
|
31
|
+
ignoreSender?: string[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export class EventBusHandler {
|
|
35
|
+
private listeners: Map<string, Set<Listeners<EventPayload>>> = new Map();
|
|
36
|
+
private responseResolvers: Map<number, (value: EventBusMessage<unknown>) => void> = new Map();
|
|
37
|
+
private static instance: EventBusHandler | null = null;
|
|
38
|
+
private debugEnabled: boolean = false;
|
|
39
|
+
private evName: string = "";
|
|
40
|
+
|
|
41
|
+
private constructor() {
|
|
42
|
+
//private constructor
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
static getInstance(name?: string) {
|
|
46
|
+
if (!EventBusHandler.instance) {
|
|
47
|
+
EventBusHandler.instance = new EventBusHandler();
|
|
48
|
+
|
|
49
|
+
EventBusHandler.instance.on("global.system.requestDebug", () => {
|
|
50
|
+
EventBusHandler.instance!.debugEnabled = true;
|
|
51
|
+
console.log(`[${EventBusHandler.instance!.evName}] Debug mode enabled. Make sure debugging messages are enabled in the browser console.`);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
if (name && EventBusHandler.instance.evName === "") {
|
|
55
|
+
EventBusHandler.instance.evName = name;
|
|
56
|
+
}
|
|
57
|
+
return EventBusHandler.instance;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private createEvent(sender: string, topic: string, data: EventPayload, eventId?: number): EventBusMessage {
|
|
61
|
+
const generatedEventId = eventId || Math.floor(Math.random() * 10000000000);
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
eventId: generatedEventId,
|
|
65
|
+
timestamp: new Date().toISOString(),
|
|
66
|
+
sender,
|
|
67
|
+
topic,
|
|
68
|
+
data,
|
|
69
|
+
debug: this.debugEnabled,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Emits an event to the event bus. Can be a new event or a response to a request.
|
|
75
|
+
* @param sender - The sender of the event.
|
|
76
|
+
* @param topic - The topic of the event.
|
|
77
|
+
* @param data - The data of the event.
|
|
78
|
+
* @param eventId - The event id of the event.
|
|
79
|
+
*
|
|
80
|
+
* The topic format is: **pluginId.area.action**
|
|
81
|
+
*
|
|
82
|
+
* Example topics:
|
|
83
|
+
* - pl1234.card.requestHard
|
|
84
|
+
* - pl1234.card.requestNew
|
|
85
|
+
* - pl1234.card.requestAll
|
|
86
|
+
* - pl1234.card.create
|
|
87
|
+
* - pl1234.card.update
|
|
88
|
+
* - pl1234.card.delete
|
|
89
|
+
* - pl1234.card.triggerBackup
|
|
90
|
+
*/
|
|
91
|
+
public emit<T = EventPayload>(sender: string, topic: string, data?: T, eventId?: number): void {
|
|
92
|
+
this.emitInternal(sender, topic, data || {}, eventId);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private emitInternal(sender: string, topic: string, data: EventPayload, eventId?: number, skipResponseTrigger = false): void {
|
|
96
|
+
if (!this.validateTopic(topic)) {
|
|
97
|
+
this.logAndThrowError(false, `Invalid topic: ` + topic);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const event = this.createEvent(sender, topic, data, eventId);
|
|
102
|
+
|
|
103
|
+
const handlers = this.getMatchingHandlers(event.topic);
|
|
104
|
+
handlers.forEach(handler => {
|
|
105
|
+
if (handler.ignoreSender && handler.ignoreSender.includes(sender)) {
|
|
106
|
+
// console.log("ignore event as its in the ignoreSender list", { event, ignoreList: handler.ignoreSender });
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
handler.handler(event);
|
|
110
|
+
});
|
|
111
|
+
this.logIfDebug(`Emitting event to ` + topic, event);
|
|
112
|
+
if (handlers.size === 0) {
|
|
113
|
+
this.logAndThrowError(false, `No handlers found for topic: ` + topic);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// If it's a response to a request
|
|
117
|
+
if (eventId && this.responseResolvers.has(eventId) && !skipResponseTrigger) {
|
|
118
|
+
// console.log("[Rimori] Resolving response to request: " + eventId, event.data);
|
|
119
|
+
this.responseResolvers.get(eventId)!(event);
|
|
120
|
+
this.responseResolvers.delete(eventId);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Subscribes to an event on the event bus.
|
|
126
|
+
* @param topics - The topic of the event.
|
|
127
|
+
* @param handler - The handler to be called when the event is emitted.
|
|
128
|
+
* @param ignoreSender - The senders to ignore.
|
|
129
|
+
* @returns The ids of the listeners.
|
|
130
|
+
*/
|
|
131
|
+
public on<T = EventPayload>(topics: string | string[], handler: EventHandler<T>, ignoreSender: string[] = []): string[] {
|
|
132
|
+
return this.toArray(topics).map(topic => {
|
|
133
|
+
if (!this.validateTopic(topic)) {
|
|
134
|
+
this.logAndThrowError(true, `Invalid topic: ` + topic);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (!this.listeners.has(topic)) {
|
|
138
|
+
this.listeners.set(topic, new Set());
|
|
139
|
+
}
|
|
140
|
+
const id = Math.floor(Math.random() * 10000000000);
|
|
141
|
+
|
|
142
|
+
// Type assertion to handle the generic type mismatch
|
|
143
|
+
const eventHandler = handler as unknown as EventHandler<EventPayload>;
|
|
144
|
+
this.listeners.get(topic)!.add({ id, handler: eventHandler, ignoreSender });
|
|
145
|
+
|
|
146
|
+
this.logIfDebug(`Subscribed to ` + topic, { listenerId: id, ignoreSender });
|
|
147
|
+
|
|
148
|
+
return btoa(JSON.stringify({ topic, id }));
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Subscribes to an event, processes the data and emits a response on the event bus.
|
|
154
|
+
* @param sender - The sender of the event.
|
|
155
|
+
* @param topic - The topic of the event.
|
|
156
|
+
* @param handler - The handler to be called when the event is received. The handler returns the data to be emitted. Can be a static object or a function.
|
|
157
|
+
* @returns The ids of the listeners.
|
|
158
|
+
*/
|
|
159
|
+
public respond(sender: string, topic: string, handler: EventPayload | ((data: EventBusMessage) => EventPayload | Promise<EventPayload>)): string[] {
|
|
160
|
+
const ids = this.on(topic, async (data: EventBusMessage) => {
|
|
161
|
+
const response = typeof handler === "function" ? await handler(data) : handler;
|
|
162
|
+
this.emit(sender, topic, response, data.eventId);
|
|
163
|
+
}, [sender]);
|
|
164
|
+
|
|
165
|
+
this.logIfDebug(`Added respond listener ` + sender + " to topic " + topic, { listenerIds: ids, sender });
|
|
166
|
+
return ids;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Subscribes to an event on the event bus. The handler will be called once and then removed.
|
|
171
|
+
* @param topic - The topic of the event.
|
|
172
|
+
* @param handler - The handler to be called when the event is emitted.
|
|
173
|
+
*/
|
|
174
|
+
public once<T = EventPayload>(topic: string, handler: EventHandler<T>): void {
|
|
175
|
+
if (!this.validateTopic(topic)) {
|
|
176
|
+
this.logAndThrowError(false, `Invalid topic: ` + topic);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
let ids: string[] = [];
|
|
181
|
+
const wrapper = (event: EventBusMessage<T>) => {
|
|
182
|
+
handler(event);
|
|
183
|
+
this.off(ids);
|
|
184
|
+
};
|
|
185
|
+
ids = this.on(topic, wrapper);
|
|
186
|
+
|
|
187
|
+
this.logIfDebug(`Added once listener ` + topic, { listenerIds: ids, topic });
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Unsubscribes from an event on the event bus.
|
|
192
|
+
* @param listenerIds - The ids of the listeners to unsubscribe from.
|
|
193
|
+
*/
|
|
194
|
+
public off(listenerIds: string | string[]): void {
|
|
195
|
+
this.toArray(listenerIds).forEach(fullId => {
|
|
196
|
+
const { topic, id } = JSON.parse(atob(fullId));
|
|
197
|
+
|
|
198
|
+
const listeners = this.listeners.get(topic) || new Set();
|
|
199
|
+
|
|
200
|
+
listeners.forEach(listener => {
|
|
201
|
+
if (listener.id === Number(id)) {
|
|
202
|
+
listeners.delete(listener);
|
|
203
|
+
this.logIfDebug(`Removed listener ` + fullId, { topic, listenerId: id });
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
private toArray(item: string | string[]): string[] {
|
|
210
|
+
return Array.isArray(item) ? item : [item];
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Requests data from the event bus.
|
|
215
|
+
* @param sender - The sender of the event.
|
|
216
|
+
* @param topic - The topic of the event.
|
|
217
|
+
* @param data - The data of the event.
|
|
218
|
+
* @returns A promise that resolves to the event.
|
|
219
|
+
*/
|
|
220
|
+
public async request<T = EventPayload>(sender: string, topic: string, data?: EventPayload): Promise<EventBusMessage<T>> {
|
|
221
|
+
if (!this.validateTopic(topic)) {
|
|
222
|
+
this.logAndThrowError(true, `Invalid topic: ` + topic);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const event = this.createEvent(sender, topic, data || {});
|
|
226
|
+
|
|
227
|
+
this.logIfDebug(`Requesting data from ` + topic, { event });
|
|
228
|
+
|
|
229
|
+
return new Promise<EventBusMessage<T>>(resolve => {
|
|
230
|
+
this.responseResolvers.set(event.eventId, (value: EventBusMessage<unknown>) => resolve(value as EventBusMessage<T>));
|
|
231
|
+
this.emitInternal(sender, topic, data || {}, event.eventId, true);
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Gets the matching handlers for an event.
|
|
237
|
+
* @param topic - The topic of the event.
|
|
238
|
+
* @returns A set of handlers that match the event type.
|
|
239
|
+
*/
|
|
240
|
+
private getMatchingHandlers(topic: string): Set<Listeners<EventPayload>> {
|
|
241
|
+
const exact = this.listeners.get(topic) || new Set();
|
|
242
|
+
|
|
243
|
+
// Find wildcard matches
|
|
244
|
+
const wildcard = [...this.listeners.entries()]
|
|
245
|
+
.filter(([key]) => key.endsWith("*") && topic.startsWith(key.slice(0, -1)))
|
|
246
|
+
.flatMap(([_, handlers]) => [...handlers]);
|
|
247
|
+
return new Set([...exact, ...wildcard]);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Validates the topic of an event.
|
|
252
|
+
* @param topic - The topic of the event.
|
|
253
|
+
* @returns True if the topic is valid, false otherwise.
|
|
254
|
+
*/
|
|
255
|
+
private validateTopic(topic: string): boolean {
|
|
256
|
+
// Split event type into parts
|
|
257
|
+
const parts = topic.split(".");
|
|
258
|
+
const [plugin, area, action] = parts;
|
|
259
|
+
|
|
260
|
+
if (parts.length !== 3) {
|
|
261
|
+
if (parts.length === 1 && plugin === "*") {
|
|
262
|
+
return true;
|
|
263
|
+
}
|
|
264
|
+
if (parts.length === 2 && plugin !== "*" && area === "*") {
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
this.logAndThrowError(false, `Event type must have 3 parts separated by dots. Received: ` + topic);
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (action === "*") {
|
|
272
|
+
return true;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Validate action part
|
|
276
|
+
const validActions = ["request", "create", "update", "delete", "trigger"];
|
|
277
|
+
|
|
278
|
+
if (validActions.some(a => action.startsWith(a))) {
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
this.logAndThrowError(false, `Invalid event topic name. The action: ` + action + ". Must be or start with one of: " + validActions.join(", "));
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
private logIfDebug(...args: (string | EventPayload)[]) {
|
|
287
|
+
if (this.debugEnabled) {
|
|
288
|
+
console.debug(`[${this.evName}] ` + args[0], ...args.slice(1));
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
private logAndThrowError(throwError: boolean, ...args: (string | EventPayload)[]) {
|
|
293
|
+
const message = `[${this.evName}] ` + args[0];
|
|
294
|
+
console.error(message, ...args.slice(1));
|
|
295
|
+
if (throwError) {
|
|
296
|
+
throw new Error(message);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export const EventBus = EventBusHandler.getInstance();
|