@rimori/client 1.1.10 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +128 -45
- package/dist/cli/scripts/init/dev-registration.d.ts +35 -0
- package/dist/cli/scripts/init/dev-registration.js +175 -0
- package/dist/cli/scripts/init/env-setup.d.ts +9 -0
- package/dist/cli/scripts/init/env-setup.js +43 -0
- package/dist/cli/scripts/init/file-operations.d.ts +4 -0
- package/dist/cli/scripts/init/file-operations.js +51 -0
- package/dist/cli/scripts/init/html-cleaner.d.ts +4 -0
- package/dist/cli/scripts/init/html-cleaner.js +38 -0
- package/dist/cli/scripts/init/main.d.ts +2 -0
- package/dist/cli/scripts/init/main.js +159 -0
- package/dist/cli/scripts/init/package-setup.d.ts +32 -0
- package/dist/cli/scripts/init/package-setup.js +75 -0
- package/dist/cli/scripts/init/router-transformer.d.ts +6 -0
- package/dist/cli/scripts/init/router-transformer.js +254 -0
- package/dist/cli/scripts/init/tailwind-config.d.ts +4 -0
- package/dist/cli/scripts/init/tailwind-config.js +56 -0
- package/dist/cli/scripts/init/vite-config.d.ts +20 -0
- package/dist/cli/scripts/init/vite-config.js +54 -0
- package/dist/cli/scripts/release/release-config-upload.d.ts +7 -0
- package/dist/cli/scripts/release/release-config-upload.js +116 -0
- package/dist/cli/scripts/release/release-db-update.d.ts +6 -0
- package/dist/cli/scripts/release/release-db-update.js +100 -0
- package/dist/cli/scripts/release/release-file-upload.d.ts +6 -0
- package/dist/cli/scripts/release/release-file-upload.js +136 -0
- package/dist/cli/scripts/release/release.d.ts +23 -0
- package/dist/cli/scripts/release/release.js +70 -0
- package/dist/cli/types/DatabaseTypes.d.ts +103 -0
- package/dist/cli/types/DatabaseTypes.js +2 -0
- package/dist/components/ai/Assistant.js +4 -4
- package/dist/components/ai/Avatar.d.ts +3 -2
- package/dist/components/ai/Avatar.js +10 -5
- package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.js +1 -1
- package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.d.ts +1 -0
- package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.js +12 -6
- package/dist/components/ai/utils.js +0 -1
- package/dist/components/audio/Playbutton.js +3 -3
- package/dist/{core → components}/components/ContextMenu.js +2 -2
- package/dist/components.d.ts +5 -5
- package/dist/components.js +5 -5
- package/dist/core/controller/AIController.d.ts +15 -0
- package/dist/core/controller/AIController.js +120 -0
- package/dist/{controller → core/controller}/ObjectController.d.ts +8 -0
- package/dist/{controller → core/controller}/SettingsController.d.ts +12 -4
- package/dist/{controller → core/controller}/SettingsController.js +0 -25
- package/dist/{controller → core/controller}/SharedContentController.d.ts +1 -1
- package/dist/{controller → core/controller}/SharedContentController.js +4 -4
- package/dist/core/core.d.ts +13 -0
- package/dist/core/core.js +8 -0
- package/dist/{plugin/fromRimori → fromRimori}/EventBus.d.ts +3 -3
- package/dist/{plugin/fromRimori → fromRimori}/EventBus.js +25 -8
- package/dist/fromRimori/PluginTypes.d.ts +171 -0
- package/dist/hooks/UseChatHook.d.ts +2 -1
- package/dist/hooks/UseChatHook.js +3 -3
- package/dist/index.d.ts +5 -3
- package/dist/index.js +4 -3
- package/dist/plugin/AccomplishmentHandler.d.ts +1 -1
- package/dist/plugin/AccomplishmentHandler.js +1 -1
- package/dist/plugin/PluginController.d.ts +16 -3
- package/dist/plugin/PluginController.js +24 -18
- package/dist/plugin/RimoriClient.d.ts +16 -11
- package/dist/plugin/RimoriClient.js +35 -25
- package/dist/plugin/StandaloneClient.js +11 -8
- package/dist/plugin/ThemeSetter.d.ts +1 -0
- package/dist/plugin/ThemeSetter.js +9 -6
- package/dist/providers/PluginProvider.d.ts +3 -0
- package/dist/providers/PluginProvider.js +4 -4
- package/dist/utils/Language.d.ts +2 -1
- package/dist/utils/Language.js +4 -2
- package/dist/utils/difficultyConverter.js +1 -1
- package/dist/utils/endpoint.d.ts +2 -0
- package/dist/utils/endpoint.js +2 -0
- package/dist/worker/WorkerSetup.js +3 -1
- package/example/docs/devdocs.md +231 -0
- package/example/docs/overview.md +29 -0
- package/example/docs/userdocs.md +123 -0
- package/example/rimori.config.ts +89 -0
- package/example/worker/vite.config.ts +23 -0
- package/example/worker/worker.ts +11 -0
- package/package.json +15 -9
- package/src/cli/scripts/init/dev-registration.ts +193 -0
- package/src/cli/scripts/init/env-setup.ts +44 -0
- package/src/cli/scripts/init/file-operations.ts +58 -0
- package/src/cli/scripts/init/html-cleaner.ts +48 -0
- package/src/cli/scripts/init/main.ts +171 -0
- package/src/cli/scripts/init/package-setup.ts +117 -0
- package/src/cli/scripts/init/router-transformer.ts +329 -0
- package/src/cli/scripts/init/tailwind-config.ts +75 -0
- package/src/cli/scripts/init/vite-config.ts +73 -0
- package/src/cli/scripts/release/release-config-upload.ts +114 -0
- package/src/cli/scripts/release/release-db-update.ts +97 -0
- package/src/cli/scripts/release/release-file-upload.ts +138 -0
- package/src/cli/scripts/release/release.ts +69 -0
- package/src/cli/types/DatabaseTypes.ts +117 -0
- package/src/components/ai/Assistant.tsx +4 -4
- package/src/components/ai/Avatar.tsx +24 -7
- package/src/components/ai/EmbeddedAssistent/CircleAudioAvatar.tsx +1 -1
- package/src/components/ai/EmbeddedAssistent/VoiceRecoder.tsx +16 -8
- package/src/components/ai/utils.ts +0 -2
- package/src/components/audio/Playbutton.tsx +3 -3
- package/src/{core → components}/components/ContextMenu.tsx +3 -3
- package/src/components.ts +6 -6
- package/src/core/controller/AIController.ts +122 -0
- package/src/core/controller/ObjectController.ts +115 -0
- package/src/{controller → core/controller}/SettingsController.ts +13 -29
- package/src/{controller → core/controller}/SharedContentController.ts +5 -5
- package/src/core/core.ts +15 -0
- package/src/{plugin/fromRimori → fromRimori}/EventBus.ts +28 -10
- package/src/fromRimori/PluginTypes.ts +203 -0
- package/src/hooks/UseChatHook.ts +5 -4
- package/src/index.ts +5 -3
- package/src/plugin/AccomplishmentHandler.ts +1 -1
- package/src/plugin/PluginController.ts +35 -23
- package/src/plugin/RimoriClient.ts +42 -35
- package/src/plugin/StandaloneClient.ts +11 -8
- package/src/plugin/ThemeSetter.ts +12 -8
- package/src/providers/PluginProvider.tsx +7 -4
- package/src/utils/Language.ts +4 -2
- package/src/utils/difficultyConverter.ts +3 -3
- package/src/utils/endpoint.ts +2 -0
- package/src/worker/WorkerSetup.ts +4 -2
- package/dist/components/PluginController.d.ts +0 -21
- package/dist/components/PluginController.js +0 -116
- package/dist/controller/AIController.d.ts +0 -23
- package/dist/controller/AIController.js +0 -93
- package/dist/controller/SidePluginController.d.ts +0 -3
- package/dist/controller/SidePluginController.js +0 -31
- package/dist/core.d.ts +0 -7
- package/dist/core.js +0 -7
- package/dist/plugin/ContextMenu.d.ts +0 -17
- package/dist/plugin/ContextMenu.js +0 -45
- package/dist/plugin/fromRimori/PluginTypes.d.ts +0 -48
- package/dist/plugin/fromRimori/SupabaseHandler.d.ts +0 -13
- package/dist/plugin/fromRimori/SupabaseHandler.js +0 -55
- package/dist/providers/PluginController.d.ts +0 -21
- package/dist/providers/PluginController.js +0 -116
- package/dist/types/Actions.d.ts +0 -4
- package/dist/types/Actions.js +0 -1
- package/src/controller/AIController.ts +0 -112
- package/src/controller/ObjectController.ts +0 -107
- package/src/controller/SidePluginController.ts +0 -25
- package/src/core.ts +0 -8
- package/src/plugin/fromRimori/PluginTypes.ts +0 -64
- package/src/types/Actions.ts +0 -6
- /package/dist/{core → components}/components/ContextMenu.d.ts +0 -0
- /package/dist/{controller → core/controller}/ObjectController.js +0 -0
- /package/dist/{controller → core/controller}/VoiceController.d.ts +0 -0
- /package/dist/{controller → core/controller}/VoiceController.js +0 -0
- /package/dist/{plugin/fromRimori → fromRimori}/PluginTypes.js +0 -0
- /package/src/{controller → core/controller}/VoiceController.ts +0 -0
- /package/src/{plugin/fromRimori → fromRimori}/readme.md +0 -0
|
@@ -1,19 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { createClient, SupabaseClient } from '@supabase/supabase-js';
|
|
2
|
+
import { UserInfo } from '../core/controller/SettingsController';
|
|
3
|
+
import { EventBus, EventBusMessage } from '../fromRimori/EventBus';
|
|
4
|
+
import { Plugin } from '../fromRimori/PluginTypes';
|
|
3
5
|
import { RimoriClient } from "./RimoriClient";
|
|
4
|
-
import { setTheme } from './ThemeSetter';
|
|
5
6
|
import { StandaloneClient } from './StandaloneClient';
|
|
7
|
+
import { setTheme } from './ThemeSetter';
|
|
6
8
|
|
|
7
9
|
// Add declaration for WorkerGlobalScope
|
|
8
10
|
declare const WorkerGlobalScope: any;
|
|
9
11
|
|
|
10
|
-
interface
|
|
12
|
+
export interface RimoriInfo {
|
|
11
13
|
url: string,
|
|
12
14
|
key: string,
|
|
15
|
+
backendUrl: string,
|
|
13
16
|
token: string,
|
|
14
17
|
expiration: Date,
|
|
15
18
|
tablePrefix: string,
|
|
16
19
|
pluginId: string
|
|
20
|
+
installedPlugins: Plugin[]
|
|
21
|
+
profile: UserInfo
|
|
17
22
|
}
|
|
18
23
|
|
|
19
24
|
export class PluginController {
|
|
@@ -21,7 +26,7 @@ export class PluginController {
|
|
|
21
26
|
private static instance: PluginController;
|
|
22
27
|
private communicationSecret: string | null = null;
|
|
23
28
|
private supabase: SupabaseClient | null = null;
|
|
24
|
-
private
|
|
29
|
+
private rimoriInfo: RimoriInfo | null = null;
|
|
25
30
|
private pluginId: string;
|
|
26
31
|
|
|
27
32
|
private constructor(pluginId: string, standalone: boolean) {
|
|
@@ -34,7 +39,7 @@ export class PluginController {
|
|
|
34
39
|
|
|
35
40
|
//no need to forward messages to parent in standalone mode
|
|
36
41
|
if (standalone) return;
|
|
37
|
-
|
|
42
|
+
|
|
38
43
|
window.addEventListener("message", (event) => {
|
|
39
44
|
// console.log("client: message received", event);
|
|
40
45
|
const { topic, sender, data, eventId } = event.data.event as EventBusMessage;
|
|
@@ -78,47 +83,54 @@ export class PluginController {
|
|
|
78
83
|
return this.communicationSecret;
|
|
79
84
|
}
|
|
80
85
|
|
|
81
|
-
public async getClient(): Promise<{ supabase: SupabaseClient,
|
|
86
|
+
public async getClient(): Promise<{ supabase: SupabaseClient, info: RimoriInfo }> {
|
|
82
87
|
if (
|
|
83
88
|
this.supabase &&
|
|
84
|
-
this.
|
|
85
|
-
this.
|
|
89
|
+
this.rimoriInfo &&
|
|
90
|
+
this.rimoriInfo.expiration > new Date()
|
|
86
91
|
) {
|
|
87
|
-
return { supabase: this.supabase,
|
|
92
|
+
return { supabase: this.supabase, info: this.rimoriInfo };
|
|
88
93
|
}
|
|
89
94
|
|
|
90
|
-
const { data } = await EventBus.request<
|
|
91
|
-
this.
|
|
92
|
-
this.supabase = createClient(this.
|
|
95
|
+
const { data } = await EventBus.request<RimoriInfo>(this.pluginId, "global.supabase.requestAccess");
|
|
96
|
+
this.rimoriInfo = data;
|
|
97
|
+
this.supabase = createClient(this.rimoriInfo.url, this.rimoriInfo.key, {
|
|
93
98
|
accessToken: () => Promise.resolve(this.getToken())
|
|
94
99
|
});
|
|
95
100
|
|
|
96
|
-
return { supabase: this.supabase,
|
|
101
|
+
return { supabase: this.supabase, info: this.rimoriInfo };
|
|
97
102
|
}
|
|
98
103
|
|
|
99
104
|
public async getToken() {
|
|
100
|
-
if (this.
|
|
101
|
-
return this.
|
|
105
|
+
if (this.rimoriInfo && this.rimoriInfo.expiration && this.rimoriInfo.expiration > new Date()) {
|
|
106
|
+
return this.rimoriInfo.token;
|
|
102
107
|
}
|
|
103
108
|
|
|
104
109
|
const { data } = await EventBus.request<{ token: string, expiration: Date }>(this.pluginId, "global.supabase.requestAccess");
|
|
105
110
|
|
|
106
|
-
if (!this.
|
|
111
|
+
if (!this.rimoriInfo) {
|
|
107
112
|
throw new Error("Supabase info not found");
|
|
108
113
|
}
|
|
109
114
|
|
|
110
|
-
this.
|
|
111
|
-
this.
|
|
115
|
+
this.rimoriInfo.token = data.token;
|
|
116
|
+
this.rimoriInfo.expiration = data.expiration;
|
|
112
117
|
|
|
113
|
-
return this.
|
|
118
|
+
return this.rimoriInfo.token;
|
|
114
119
|
}
|
|
115
120
|
|
|
116
121
|
public getSupabaseUrl() {
|
|
117
|
-
if (!this.
|
|
122
|
+
if (!this.rimoriInfo) {
|
|
118
123
|
throw new Error("Supabase info not found");
|
|
119
124
|
}
|
|
120
125
|
|
|
121
|
-
return this.
|
|
126
|
+
return this.rimoriInfo.url;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
public getBackendUrl() {
|
|
130
|
+
if (!this.rimoriInfo) {
|
|
131
|
+
throw new Error("Rimori info not found");
|
|
132
|
+
}
|
|
133
|
+
return this.rimoriInfo.backendUrl;
|
|
122
134
|
}
|
|
123
135
|
|
|
124
136
|
public getGlobalEventTopic(preliminaryTopic: string) {
|
|
@@ -138,7 +150,7 @@ export class PluginController {
|
|
|
138
150
|
throw new Error(`The event topic must consist of 3 parts. <pluginId>.<topic area>.<action>. Received: ${preliminaryTopic}`);
|
|
139
151
|
}
|
|
140
152
|
|
|
141
|
-
const topicRoot = this.
|
|
153
|
+
const topicRoot = this.rimoriInfo?.pluginId ?? "global";
|
|
142
154
|
return `${topicRoot}.${preliminaryTopic}`;
|
|
143
155
|
}
|
|
144
156
|
|
|
@@ -1,23 +1,16 @@
|
|
|
1
1
|
import { PostgrestQueryBuilder } from "@supabase/postgrest-js";
|
|
2
2
|
import { SupabaseClient } from "@supabase/supabase-js";
|
|
3
3
|
import { GenericSchema } from "@supabase/supabase-js/dist/module/lib/types";
|
|
4
|
-
import { generateText, Message, OnLLMResponse, streamChatGPT
|
|
5
|
-
import { generateObject as generateObjectFunction, ObjectRequest } from "../controller/ObjectController";
|
|
6
|
-
import { SettingsController, UserInfo } from "../controller/SettingsController";
|
|
7
|
-
import { SharedContent, SharedContentController, SharedContentFilter, SharedContentObjectRequest } from "../controller/SharedContentController";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
4
|
+
import { generateText, Message, OnLLMResponse, streamChatGPT } from "../core/controller/AIController";
|
|
5
|
+
import { generateObject as generateObjectFunction, ObjectRequest } from "../core/controller/ObjectController";
|
|
6
|
+
import { SettingsController, UserInfo } from "../core/controller/SettingsController";
|
|
7
|
+
import { SharedContent, SharedContentController, SharedContentFilter, SharedContentObjectRequest } from "../core/controller/SharedContentController";
|
|
8
|
+
import { getSTTResponse, getTTSResponse } from "../core/controller/VoiceController";
|
|
9
|
+
import { EventBus, EventBusMessage, EventHandler, EventPayload } from "../fromRimori/EventBus";
|
|
10
|
+
import { Plugin, Tool } from "../fromRimori/PluginTypes";
|
|
10
11
|
import { AccomplishmentHandler, AccomplishmentPayload } from "./AccomplishmentHandler";
|
|
11
|
-
import {
|
|
12
|
-
import { Plugin } from "./fromRimori/PluginTypes";
|
|
13
|
-
import { PluginController } from "./PluginController";
|
|
12
|
+
import { PluginController, RimoriInfo } from "./PluginController";
|
|
14
13
|
|
|
15
|
-
interface RimoriClientOptions {
|
|
16
|
-
pluginController: PluginController;
|
|
17
|
-
supabase: SupabaseClient;
|
|
18
|
-
tablePrefix: string;
|
|
19
|
-
pluginId: string;
|
|
20
|
-
}
|
|
21
14
|
|
|
22
15
|
interface Db {
|
|
23
16
|
from: {
|
|
@@ -66,16 +59,20 @@ export class RimoriClient {
|
|
|
66
59
|
private sharedContentController: SharedContentController;
|
|
67
60
|
private accomplishmentHandler: AccomplishmentHandler;
|
|
68
61
|
private supabaseUrl: string;
|
|
69
|
-
|
|
62
|
+
private installedPlugins: Plugin[];
|
|
63
|
+
private profile: UserInfo;
|
|
70
64
|
public plugin: PluginInterface;
|
|
65
|
+
public db: Db;
|
|
71
66
|
|
|
72
|
-
private constructor(
|
|
73
|
-
this.superbase =
|
|
74
|
-
this.pluginController =
|
|
75
|
-
this.settingsController = new SettingsController(
|
|
67
|
+
private constructor(supabase: SupabaseClient, info: RimoriInfo, pluginController: PluginController) {
|
|
68
|
+
this.superbase = supabase;
|
|
69
|
+
this.pluginController = pluginController;
|
|
70
|
+
this.settingsController = new SettingsController(supabase, info.pluginId);
|
|
76
71
|
this.sharedContentController = new SharedContentController(this.superbase, this);
|
|
77
72
|
this.supabaseUrl = this.pluginController.getSupabaseUrl();
|
|
78
|
-
this.accomplishmentHandler = new AccomplishmentHandler(
|
|
73
|
+
this.accomplishmentHandler = new AccomplishmentHandler(info.pluginId);
|
|
74
|
+
this.installedPlugins = info.installedPlugins;
|
|
75
|
+
this.profile = info.profile;
|
|
79
76
|
|
|
80
77
|
this.from = this.from.bind(this);
|
|
81
78
|
|
|
@@ -83,11 +80,11 @@ export class RimoriClient {
|
|
|
83
80
|
from: this.from,
|
|
84
81
|
storage: this.superbase.storage,
|
|
85
82
|
// functions: this.superbase.functions,
|
|
86
|
-
tablePrefix:
|
|
83
|
+
tablePrefix: info.tablePrefix,
|
|
87
84
|
getTableName: this.getTableName.bind(this),
|
|
88
85
|
}
|
|
89
86
|
this.plugin = {
|
|
90
|
-
pluginId:
|
|
87
|
+
pluginId: info.pluginId,
|
|
91
88
|
setSettings: async (settings: any) => {
|
|
92
89
|
await this.settingsController.setSettings(settings);
|
|
93
90
|
},
|
|
@@ -95,10 +92,10 @@ export class RimoriClient {
|
|
|
95
92
|
return await this.settingsController.getSettings<T>(defaultSettings);
|
|
96
93
|
},
|
|
97
94
|
getInstalled: async (): Promise<Plugin[]> => {
|
|
98
|
-
return
|
|
95
|
+
return this.installedPlugins;
|
|
99
96
|
},
|
|
100
97
|
getUserInfo: async (): Promise<UserInfo> => {
|
|
101
|
-
return this.
|
|
98
|
+
return this.profile;
|
|
102
99
|
}
|
|
103
100
|
}
|
|
104
101
|
}
|
|
@@ -132,11 +129,11 @@ export class RimoriClient {
|
|
|
132
129
|
* Subscribe to an event.
|
|
133
130
|
* @param topic The topic to subscribe to.
|
|
134
131
|
* @param callback The callback to call when the event is emitted.
|
|
135
|
-
* @returns
|
|
132
|
+
* @returns An EventListener object containing an off() method to unsubscribe the listeners.
|
|
136
133
|
*/
|
|
137
134
|
on: <T = EventPayload>(topic: string | string[], callback: EventHandler<T>) => {
|
|
138
135
|
const topics = Array.isArray(topic) ? topic : [topic];
|
|
139
|
-
return topics.map(
|
|
136
|
+
return EventBus.on<T>(topics.map(t => this.pluginController.getGlobalEventTopic(t)), callback);
|
|
140
137
|
},
|
|
141
138
|
/**
|
|
142
139
|
* Subscribe to an event once.
|
|
@@ -151,8 +148,9 @@ export class RimoriClient {
|
|
|
151
148
|
* @param topic The topic to respond to.
|
|
152
149
|
* @param data The data to respond with.
|
|
153
150
|
*/
|
|
154
|
-
respond: <T = EventPayload>(topic: string, data: EventPayload | ((data: EventBusMessage<T>) => EventPayload | Promise<EventPayload>)) => {
|
|
155
|
-
|
|
151
|
+
respond: <T = EventPayload>(topic: string | string[], data: EventPayload | ((data: EventBusMessage<T>) => EventPayload | Promise<EventPayload>)) => {
|
|
152
|
+
const topics = Array.isArray(topic) ? topic : [topic];
|
|
153
|
+
EventBus.respond(this.plugin.pluginId, topics.map(t => this.pluginController.getGlobalEventTopic(t)), data);
|
|
156
154
|
},
|
|
157
155
|
/**
|
|
158
156
|
* Emit an accomplishment.
|
|
@@ -176,14 +174,20 @@ export class RimoriClient {
|
|
|
176
174
|
* @param text Optional text to be used for the action like for example text that the translator would look up.
|
|
177
175
|
*/
|
|
178
176
|
emitSidebarAction: (pluginId: string, actionKey: string, text?: string) => {
|
|
179
|
-
this.event.emit("global.sidebar.triggerAction", { pluginId, actionKey, text });
|
|
177
|
+
this.event.emit("global.sidebar.triggerAction", { plugin_id: pluginId, action_key: actionKey, text });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
public navigation = {
|
|
182
|
+
toDashboard: () => {
|
|
183
|
+
this.event.emit("global.navigation.triggerToDashboard");
|
|
180
184
|
}
|
|
181
185
|
}
|
|
182
186
|
|
|
183
187
|
public static async getInstance(pluginController: PluginController): Promise<RimoriClient> {
|
|
184
188
|
if (!RimoriClient.instance) {
|
|
185
|
-
const
|
|
186
|
-
RimoriClient.instance = new RimoriClient(
|
|
189
|
+
const client = await pluginController.getClient();
|
|
190
|
+
RimoriClient.instance = new RimoriClient(client.supabase, client.info, pluginController);
|
|
187
191
|
}
|
|
188
192
|
return RimoriClient.instance;
|
|
189
193
|
}
|
|
@@ -201,17 +205,20 @@ export class RimoriClient {
|
|
|
201
205
|
}
|
|
202
206
|
|
|
203
207
|
private getTableName(type: string) {
|
|
208
|
+
if (type.startsWith("global_")) {
|
|
209
|
+
return type.replace("global_", "");
|
|
210
|
+
}
|
|
204
211
|
return this.db.tablePrefix + "_" + type;
|
|
205
212
|
}
|
|
206
213
|
|
|
207
|
-
public
|
|
214
|
+
public ai = {
|
|
208
215
|
getText: async (messages: Message[], tools?: Tool[]): Promise<string> => {
|
|
209
216
|
const token = await this.pluginController.getToken();
|
|
210
|
-
return generateText(this.
|
|
217
|
+
return generateText(this.pluginController.getBackendUrl(), messages, tools || [], token).then(({ messages }) => messages[0].content[0].text);
|
|
211
218
|
},
|
|
212
219
|
getSteamedText: async (messages: Message[], onMessage: OnLLMResponse, tools?: Tool[]) => {
|
|
213
220
|
const token = await this.pluginController.getToken();
|
|
214
|
-
streamChatGPT(this.
|
|
221
|
+
streamChatGPT(this.pluginController.getBackendUrl(), messages, tools || [], onMessage, token);
|
|
215
222
|
},
|
|
216
223
|
getVoice: async (text: string, voice = "alloy", speed = 1, language?: string): Promise<Blob> => {
|
|
217
224
|
const token = await this.pluginController.getToken();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { EventBus } from "./fromRimori/EventBus";
|
|
2
1
|
import { createClient, SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
import { EventBus } from "../fromRimori/EventBus";
|
|
3
|
+
import { DEFAULT_ANON_KEY, DEFAULT_ENDPOINT } from "../utils/endpoint";
|
|
3
4
|
|
|
4
5
|
export interface StandaloneConfig {
|
|
5
6
|
url: string,
|
|
@@ -18,14 +19,13 @@ export class StandaloneClient {
|
|
|
18
19
|
|
|
19
20
|
public static async getInstance(): Promise<StandaloneClient> {
|
|
20
21
|
if (!StandaloneClient.instance) {
|
|
21
|
-
const config = await fetch("
|
|
22
|
+
const config = await fetch("https://app.rimori.se/config.json").then(res => res.json()).catch(err => {
|
|
22
23
|
console.warn("Error fetching config.json, using default values", err);
|
|
23
|
-
return {
|
|
24
|
-
SUPABASE_URL: "https://pheptqdoqsdnadgoihvr.supabase.co",
|
|
25
|
-
SUPABASE_ANON_KEY: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBoZXB0cWRvcXNkbmFkZ29paHZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MzE2OTY2ODcsImV4cCI6MjA0NzI3MjY4N30.4GPFAXTF8685FaXISdAPNCIM-H3RGLo8GbyhQpu1mP0",
|
|
26
|
-
}
|
|
27
24
|
});
|
|
28
|
-
StandaloneClient.instance = new StandaloneClient({
|
|
25
|
+
StandaloneClient.instance = new StandaloneClient({
|
|
26
|
+
url: config?.SUPABASE_URL || DEFAULT_ENDPOINT,
|
|
27
|
+
key: config?.SUPABASE_ANON_KEY || DEFAULT_ANON_KEY,
|
|
28
|
+
});
|
|
29
29
|
}
|
|
30
30
|
return StandaloneClient.instance;
|
|
31
31
|
}
|
|
@@ -58,7 +58,10 @@ export class StandaloneClient {
|
|
|
58
58
|
EventBus.respond("standalone", "global.supabase.requestAccess", async () => {
|
|
59
59
|
const session = await supabase.auth.getSession();
|
|
60
60
|
console.log("session", session);
|
|
61
|
-
const { data, error } = await supabase.functions.invoke("plugin-token", {
|
|
61
|
+
const { data, error } = await supabase.functions.invoke("plugin-token", {
|
|
62
|
+
body: { pluginId },
|
|
63
|
+
headers: { authorization: `Bearer ${session.data.session?.access_token}` },
|
|
64
|
+
});
|
|
62
65
|
if (error) {
|
|
63
66
|
throw new Error("Failed to get plugin token. " + error.message);
|
|
64
67
|
}
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
export function setTheme() {
|
|
2
|
-
const urlParams = new URLSearchParams(window.location.search);
|
|
3
|
-
|
|
4
|
-
let theme = urlParams.get('theme');
|
|
5
|
-
if (!theme || theme === 'system') {
|
|
6
|
-
theme = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
7
|
-
}
|
|
8
|
-
|
|
9
2
|
document.documentElement.classList.add("dark:text-gray-200");
|
|
10
3
|
|
|
11
|
-
if (
|
|
4
|
+
if (isDarkTheme()) {
|
|
12
5
|
document.documentElement.setAttribute("data-theme", "dark");
|
|
13
6
|
document.documentElement.classList.add('dark', "dark:bg-gray-950");
|
|
14
7
|
document.documentElement.style.background = "hsl(var(--background))";
|
|
15
8
|
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function isDarkTheme(): boolean {
|
|
12
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
13
|
+
|
|
14
|
+
let theme = urlParams.get('theme');
|
|
15
|
+
if (!theme || theme === 'system') {
|
|
16
|
+
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return theme === 'dark';
|
|
16
20
|
}
|
|
@@ -1,18 +1,21 @@
|
|
|
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 { EventBusHandler } from '../
|
|
5
|
-
import ContextMenu from '../
|
|
4
|
+
import { EventBusHandler } from '../fromRimori/EventBus';
|
|
5
|
+
import ContextMenu from '../components/components/ContextMenu';
|
|
6
6
|
import { StandaloneClient } from '../plugin/StandaloneClient';
|
|
7
7
|
|
|
8
8
|
interface PluginProviderProps {
|
|
9
9
|
children: ReactNode;
|
|
10
10
|
pluginId: string;
|
|
11
|
+
settings?: {
|
|
12
|
+
disableContextMenu?: boolean;
|
|
13
|
+
}
|
|
11
14
|
}
|
|
12
15
|
|
|
13
16
|
const PluginContext = createContext<RimoriClient | null>(null);
|
|
14
17
|
|
|
15
|
-
export const PluginProvider: React.FC<PluginProviderProps> = ({ children, pluginId }) => {
|
|
18
|
+
export const PluginProvider: React.FC<PluginProviderProps> = ({ children, pluginId, settings }) => {
|
|
16
19
|
const [plugin, setPlugin] = useState<RimoriClient | null>(null);
|
|
17
20
|
const [standaloneClient, setStandaloneClient] = useState<StandaloneClient | boolean>(false);
|
|
18
21
|
|
|
@@ -73,7 +76,7 @@ export const PluginProvider: React.FC<PluginProviderProps> = ({ children, plugin
|
|
|
73
76
|
|
|
74
77
|
return (
|
|
75
78
|
<PluginContext.Provider value={plugin}>
|
|
76
|
-
<ContextMenu client={plugin} />
|
|
79
|
+
{!settings?.disableContextMenu && <ContextMenu client={plugin} />}
|
|
77
80
|
{children}
|
|
78
81
|
</PluginContext.Provider>
|
|
79
82
|
);
|
package/src/utils/Language.ts
CHANGED
|
@@ -63,8 +63,10 @@ export type Language = keyof typeof languageKeys;
|
|
|
63
63
|
/**
|
|
64
64
|
* Get the language name from the language code
|
|
65
65
|
* @param languageCode The code of the language
|
|
66
|
+
* @param capitalize Whether to capitalize the first letter of the language name
|
|
66
67
|
* @returns The language name
|
|
67
68
|
*/
|
|
68
|
-
export function getLanguageName(languageCode: Language): string {
|
|
69
|
-
|
|
69
|
+
export function getLanguageName(languageCode: Language, capitalize: boolean = false): string {
|
|
70
|
+
const lang = languageKeys[languageCode];
|
|
71
|
+
return capitalize ? lang.charAt(0).toUpperCase() + lang.slice(1) : lang;
|
|
70
72
|
}
|
|
@@ -3,13 +3,13 @@ const codes = ["Pre-A1", "A1", "A2", "B1", "B2", "C1", "C2", "Post-C2"];
|
|
|
3
3
|
export type LanguageLevel = "Pre-A1" | "A1" | "A2" | "B1" | "B2" | "C1" | "C2" | "Post-C2";
|
|
4
4
|
|
|
5
5
|
export function getDifficultyLevel(difficulty: LanguageLevel): number {
|
|
6
|
-
|
|
6
|
+
return codes.indexOf(difficulty) + 1;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export function getDifficultyLabel(difficulty: number): LanguageLevel {
|
|
10
|
-
|
|
10
|
+
return codes[difficulty] as LanguageLevel;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export function getNeighborDifficultyLevel(difficulty: LanguageLevel, difficultyAdjustment: number): LanguageLevel {
|
|
14
|
-
|
|
14
|
+
return getDifficultyLabel(getDifficultyLevel(difficulty) + difficultyAdjustment - 1);
|
|
15
15
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export const DEFAULT_ENDPOINT = "https://pheptqdoqsdnadgoihvr.supabase.co";
|
|
2
|
+
export const DEFAULT_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBoZXB0cWRvcXNkbmFkZ29paHZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MzE2OTY2ODcsImV4cCI6MjA0NzI3MjY4N30.4GPFAXTF8685FaXISdAPNCIM-H3RGLo8GbyhQpu1mP0";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EventBus, EventBusHandler, EventBusMessage } from "../fromRimori/EventBus";
|
|
2
2
|
import { PluginController } from "../plugin/PluginController";
|
|
3
|
-
import {
|
|
3
|
+
import { RimoriClient } from "../plugin/RimoriClient";
|
|
4
4
|
|
|
5
5
|
let controller: RimoriClient | null = null;
|
|
6
6
|
const listeners: ((event: { data: { event: EventBusMessage, secret: string } }) => void)[] = [];
|
|
@@ -29,6 +29,7 @@ export function setupWorker(init: (controller: RimoriClient) => void | Promise<v
|
|
|
29
29
|
APP_CONFIG: {
|
|
30
30
|
SUPABASE_URL: 'NOT_SET',
|
|
31
31
|
SUPABASE_ANON_KEY: 'NOT_SET',
|
|
32
|
+
BACKEND_URL: 'NOT_SET',
|
|
32
33
|
},
|
|
33
34
|
};
|
|
34
35
|
|
|
@@ -48,6 +49,7 @@ export function setupWorker(init: (controller: RimoriClient) => void | Promise<v
|
|
|
48
49
|
if (!controller) {
|
|
49
50
|
mockWindow.APP_CONFIG.SUPABASE_URL = event.data.supabaseUrl;
|
|
50
51
|
mockWindow.APP_CONFIG.SUPABASE_ANON_KEY = event.data.supabaseAnonKey;
|
|
52
|
+
mockWindow.APP_CONFIG.BACKEND_URL = event.data.backendUrl;
|
|
51
53
|
controller = await PluginController.getInstance(event.data.pluginId);
|
|
52
54
|
logIfDebug('Worker initialized.');
|
|
53
55
|
await init(controller);
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { SupabaseClient } from '@supabase/supabase-js';
|
|
2
|
-
import { RimoriClient } from "../plugin/RimoriClient";
|
|
3
|
-
export declare class PluginController {
|
|
4
|
-
private static client;
|
|
5
|
-
private static instance;
|
|
6
|
-
private communicationSecret;
|
|
7
|
-
private supabase;
|
|
8
|
-
private supabaseInfo;
|
|
9
|
-
private pluginId;
|
|
10
|
-
private constructor();
|
|
11
|
-
static getInstance(sender: string): Promise<RimoriClient>;
|
|
12
|
-
private getSecret;
|
|
13
|
-
getClient(): Promise<{
|
|
14
|
-
supabase: SupabaseClient;
|
|
15
|
-
tablePrefix: string;
|
|
16
|
-
pluginId: string;
|
|
17
|
-
}>;
|
|
18
|
-
getToken(): Promise<string>;
|
|
19
|
-
getSupabaseUrl(): string;
|
|
20
|
-
getGlobalEventTopic(preliminaryTopic: string): string;
|
|
21
|
-
}
|
|
@@ -1,116 +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 { createClient } from '@supabase/supabase-js';
|
|
11
|
-
import { EventBus } from '../plugin/fromRimori/EventBus';
|
|
12
|
-
import { RimoriClient } from "../plugin/RimoriClient";
|
|
13
|
-
import { setTheme } from '../plugin/ThemeSetter';
|
|
14
|
-
export class PluginController {
|
|
15
|
-
constructor(pluginId) {
|
|
16
|
-
this.communicationSecret = null;
|
|
17
|
-
this.supabase = null;
|
|
18
|
-
this.supabaseInfo = null;
|
|
19
|
-
this.pluginId = pluginId;
|
|
20
|
-
this.getClient = this.getClient.bind(this);
|
|
21
|
-
if (typeof WorkerGlobalScope === 'undefined') {
|
|
22
|
-
setTheme();
|
|
23
|
-
}
|
|
24
|
-
window.addEventListener("message", (event) => {
|
|
25
|
-
// console.log("client: message received", event);
|
|
26
|
-
const { topic, sender, data, eventId } = event.data.event;
|
|
27
|
-
// skip forwarding messages from own plugin
|
|
28
|
-
if (sender === pluginId)
|
|
29
|
-
return;
|
|
30
|
-
EventBus.emit(sender, topic, data, eventId);
|
|
31
|
-
});
|
|
32
|
-
EventBus.on("*", (event) => {
|
|
33
|
-
// skip messages which are not from the own plugin
|
|
34
|
-
if (event.sender !== this.pluginId)
|
|
35
|
-
return;
|
|
36
|
-
if (event.topic.startsWith("self."))
|
|
37
|
-
return;
|
|
38
|
-
window.parent.postMessage({ event, secret: this.getSecret() }, "*");
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
static getInstance(sender) {
|
|
42
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
-
if (!PluginController.instance) {
|
|
44
|
-
PluginController.instance = new PluginController(sender);
|
|
45
|
-
PluginController.client = yield RimoriClient.getInstance(PluginController.instance);
|
|
46
|
-
}
|
|
47
|
-
return PluginController.client;
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
getSecret() {
|
|
51
|
-
if (!this.communicationSecret) {
|
|
52
|
-
const secret = new URLSearchParams(window.location.search).get("secret");
|
|
53
|
-
if (!secret) {
|
|
54
|
-
throw new Error("Communication secret not found in URL as query parameter");
|
|
55
|
-
}
|
|
56
|
-
this.communicationSecret = secret;
|
|
57
|
-
}
|
|
58
|
-
return this.communicationSecret;
|
|
59
|
-
}
|
|
60
|
-
getClient() {
|
|
61
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
-
if (this.supabase &&
|
|
63
|
-
this.supabaseInfo &&
|
|
64
|
-
this.supabaseInfo.expiration > new Date()) {
|
|
65
|
-
return { supabase: this.supabase, tablePrefix: this.supabaseInfo.tablePrefix, pluginId: this.supabaseInfo.pluginId };
|
|
66
|
-
}
|
|
67
|
-
const { data } = yield EventBus.request(this.pluginId, "global.supabase.requestAccess");
|
|
68
|
-
this.supabaseInfo = data;
|
|
69
|
-
this.supabase = createClient(this.supabaseInfo.url, this.supabaseInfo.key, {
|
|
70
|
-
accessToken: () => Promise.resolve(this.getToken())
|
|
71
|
-
});
|
|
72
|
-
return { supabase: this.supabase, tablePrefix: this.supabaseInfo.tablePrefix, pluginId: this.supabaseInfo.pluginId };
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
getToken() {
|
|
76
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
77
|
-
if (this.supabaseInfo && this.supabaseInfo.expiration && this.supabaseInfo.expiration > new Date()) {
|
|
78
|
-
return this.supabaseInfo.token;
|
|
79
|
-
}
|
|
80
|
-
const { data } = yield EventBus.request(this.pluginId, "global.supabase.requestAccess");
|
|
81
|
-
if (!this.supabaseInfo) {
|
|
82
|
-
throw new Error("Supabase info not found");
|
|
83
|
-
}
|
|
84
|
-
this.supabaseInfo.token = data.token;
|
|
85
|
-
this.supabaseInfo.expiration = data.expiration;
|
|
86
|
-
return this.supabaseInfo.token;
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
getSupabaseUrl() {
|
|
90
|
-
if (!this.supabaseInfo) {
|
|
91
|
-
throw new Error("Supabase info not found");
|
|
92
|
-
}
|
|
93
|
-
return this.supabaseInfo.url;
|
|
94
|
-
}
|
|
95
|
-
getGlobalEventTopic(preliminaryTopic) {
|
|
96
|
-
var _a, _b;
|
|
97
|
-
if (preliminaryTopic.startsWith("global.")) {
|
|
98
|
-
return preliminaryTopic;
|
|
99
|
-
}
|
|
100
|
-
if (preliminaryTopic.startsWith("self.")) {
|
|
101
|
-
return preliminaryTopic;
|
|
102
|
-
}
|
|
103
|
-
const topicParts = preliminaryTopic.split(".");
|
|
104
|
-
if (topicParts.length === 3) {
|
|
105
|
-
if (!topicParts[0].startsWith("pl") && topicParts[0] !== "global") {
|
|
106
|
-
throw new Error("The event topic must start with the plugin id or 'global'.");
|
|
107
|
-
}
|
|
108
|
-
return preliminaryTopic;
|
|
109
|
-
}
|
|
110
|
-
else if (topicParts.length > 3) {
|
|
111
|
-
throw new Error(`The event topic must consist of 3 parts. <pluginId>.<topic area>.<action>. Received: ${preliminaryTopic}`);
|
|
112
|
-
}
|
|
113
|
-
const topicRoot = (_b = (_a = this.supabaseInfo) === null || _a === void 0 ? void 0 : _a.pluginId) !== null && _b !== void 0 ? _b : "global";
|
|
114
|
-
return `${topicRoot}.${preliminaryTopic}`;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
@@ -1,23 +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
|
-
description: string;
|
|
11
|
-
type: "string" | "number" | "boolean";
|
|
12
|
-
}[];
|
|
13
|
-
execute?: <T = Record<string, string | boolean | number>>(args: T) => Promise<any> | void;
|
|
14
|
-
}
|
|
15
|
-
export interface Message {
|
|
16
|
-
id: string;
|
|
17
|
-
role: string;
|
|
18
|
-
content: string;
|
|
19
|
-
toolInvocations?: ToolInvocation[];
|
|
20
|
-
}
|
|
21
|
-
export declare function generateText(supabaseUrl: string, messages: Message[], tools: Tool[], token: string): Promise<any>;
|
|
22
|
-
export type OnLLMResponse = (id: string, response: string, finished: boolean, toolInvocations?: ToolInvocation[]) => void;
|
|
23
|
-
export declare function streamChatGPT(supabaseUrl: string, messages: Message[], tools: Tool[], onResponse: OnLLMResponse, token: string): Promise<void>;
|