@rimori/client 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/dist/CRUDModal.d.ts +16 -0
  2. package/dist/CRUDModal.js +31 -0
  3. package/dist/MarkdownEditor.d.ts +8 -0
  4. package/dist/MarkdownEditor.js +46 -0
  5. package/dist/audio/Playbutton.d.ts +14 -0
  6. package/dist/audio/Playbutton.js +73 -0
  7. package/dist/components/CRUDModal.d.ts +17 -0
  8. package/dist/components/CRUDModal.js +25 -0
  9. package/dist/components/MarkdownEditor.d.ts +8 -0
  10. package/dist/components/MarkdownEditor.js +46 -0
  11. package/dist/components/Spinner.d.ts +8 -0
  12. package/dist/components/Spinner.js +5 -0
  13. package/dist/components/audio/Playbutton.d.ts +15 -0
  14. package/dist/components/audio/Playbutton.js +78 -0
  15. package/dist/components/hooks/UseChatHook.d.ts +15 -0
  16. package/dist/components/hooks/UseChatHook.js +21 -0
  17. package/dist/controller/AIController.d.ts +22 -0
  18. package/dist/controller/AIController.js +68 -0
  19. package/dist/controller/ObjectController.d.ts +34 -0
  20. package/dist/controller/ObjectController.js +77 -0
  21. package/dist/controller/SettingsController.d.ts +24 -0
  22. package/dist/controller/SettingsController.js +72 -0
  23. package/dist/controller/SharedContentController.d.ts +22 -0
  24. package/dist/controller/SharedContentController.js +56 -0
  25. package/dist/controller/VoiceController.d.ts +10 -0
  26. package/dist/controller/VoiceController.js +28 -0
  27. package/dist/hooks/UseChatHook.d.ts +9 -0
  28. package/dist/hooks/UseChatHook.js +21 -0
  29. package/dist/index.d.ts +14 -0
  30. package/dist/index.js +14 -0
  31. package/dist/plugin/AIController copy.d.ts +22 -0
  32. package/dist/plugin/AIController copy.js +68 -0
  33. package/dist/plugin/AIController.d.ts +22 -0
  34. package/dist/plugin/AIController.js +68 -0
  35. package/dist/plugin/ObjectController.d.ts +34 -0
  36. package/dist/plugin/ObjectController.js +77 -0
  37. package/dist/plugin/PluginController.d.ts +29 -0
  38. package/dist/plugin/PluginController.js +138 -0
  39. package/dist/plugin/RimoriClient.d.ts +91 -0
  40. package/dist/plugin/RimoriClient.js +163 -0
  41. package/dist/plugin/SettingController.d.ts +13 -0
  42. package/dist/plugin/SettingController.js +55 -0
  43. package/dist/plugin/ThemeSetter.d.ts +1 -0
  44. package/dist/plugin/ThemeSetter.js +13 -0
  45. package/dist/plugin/VoiceController.d.ts +2 -0
  46. package/dist/plugin/VoiceController.js +27 -0
  47. package/dist/providers/EventEmitter.d.ts +11 -0
  48. package/dist/providers/EventEmitter.js +41 -0
  49. package/dist/providers/EventEmitterContext.d.ts +6 -0
  50. package/dist/providers/EventEmitterContext.js +19 -0
  51. package/dist/providers/PluginProvider.d.ts +8 -0
  52. package/dist/providers/PluginProvider.js +52 -0
  53. package/dist/style.css +110 -0
  54. package/dist/style.css.map +1 -0
  55. package/dist/utils/DifficultyConverter.d.ts +3 -0
  56. package/dist/utils/DifficultyConverter.js +7 -0
  57. package/dist/utils/PluginUtils.d.ts +2 -0
  58. package/dist/utils/PluginUtils.js +23 -0
  59. package/dist/utils/constants.d.ts +4 -0
  60. package/dist/utils/constants.js +12 -0
  61. package/dist/utils/difficultyConverter.d.ts +3 -0
  62. package/dist/utils/difficultyConverter.js +7 -0
  63. package/dist/utils/plugin/Client.d.ts +72 -0
  64. package/dist/utils/plugin/Client.js +118 -0
  65. package/dist/utils/plugin/PluginController.d.ts +36 -0
  66. package/dist/utils/plugin/PluginController.js +119 -0
  67. package/dist/utils/plugin/PluginUtils.d.ts +2 -0
  68. package/dist/utils/plugin/PluginUtils.js +23 -0
  69. package/dist/utils/plugin/RimoriClient.d.ts +72 -0
  70. package/dist/utils/plugin/RimoriClient.js +118 -0
  71. package/dist/utils/plugin/ThemeSetter.d.ts +1 -0
  72. package/dist/utils/plugin/ThemeSetter.js +13 -0
  73. package/dist/utils/plugin/WhereClauseBuilder.d.ts +24 -0
  74. package/dist/utils/plugin/WhereClauseBuilder.js +79 -0
  75. package/dist/utils/plugin/providers/EventEmitter.d.ts +11 -0
  76. package/dist/utils/plugin/providers/EventEmitter.js +41 -0
  77. package/dist/utils/plugin/providers/EventEmitterContext.d.ts +6 -0
  78. package/dist/utils/plugin/providers/EventEmitterContext.js +19 -0
  79. package/dist/utils/plugin/providers/PluginProvider.d.ts +8 -0
  80. package/dist/utils/plugin/providers/PluginProvider.js +49 -0
  81. package/package.json +30 -0
  82. package/src/components/CRUDModal.tsx +61 -0
  83. package/src/components/MarkdownEditor.tsx +111 -0
  84. package/src/components/Spinner.tsx +24 -0
  85. package/src/components/audio/Playbutton.tsx +119 -0
  86. package/src/controller/AIController.ts +87 -0
  87. package/src/controller/ObjectController.ts +109 -0
  88. package/src/controller/SettingsController.ts +87 -0
  89. package/src/controller/SharedContentController.ts +71 -0
  90. package/src/controller/VoiceController.ts +26 -0
  91. package/src/hooks/UseChatHook.ts +25 -0
  92. package/src/index.ts +14 -0
  93. package/src/plugin/PluginController.ts +158 -0
  94. package/src/plugin/RimoriClient.ts +207 -0
  95. package/src/plugin/ThemeSetter.ts +17 -0
  96. package/src/providers/EventEmitter.ts +48 -0
  97. package/src/providers/EventEmitterContext.tsx +27 -0
  98. package/src/providers/PluginProvider.tsx +68 -0
  99. package/src/style.scss +136 -0
  100. package/src/utils/PluginUtils.ts +26 -0
  101. package/src/utils/constants.ts +18 -0
  102. package/src/utils/difficultyConverter.ts +11 -0
  103. package/tsconfig.json +16 -0
@@ -0,0 +1,29 @@
1
+ import { SupabaseClient } from '@supabase/supabase-js';
2
+ import { RimoriClient } from "./RimoriClient";
3
+ export declare class PluginController {
4
+ private static instance;
5
+ private static client;
6
+ private plugin;
7
+ private onceListeners;
8
+ private listeners;
9
+ private communicationSecret;
10
+ private initialized;
11
+ private supabase;
12
+ private supabaseInfo;
13
+ private constructor();
14
+ static getInstance(): Promise<RimoriClient>;
15
+ init(): Promise<void>;
16
+ private getSecret;
17
+ getClient(): Promise<{
18
+ supabase: SupabaseClient;
19
+ tablePrefix: string;
20
+ pluginId: string;
21
+ }>;
22
+ getToken(): Promise<string>;
23
+ getSupabaseUrl(): string;
24
+ emit(eventName: string, data?: any): void;
25
+ private internalEmit;
26
+ subscribe(eventName: string, callback: (_id: number, data: any) => void): void;
27
+ onOnce(eventName: string, callback: (data: any) => void): void;
28
+ request<T>(topic: string, data?: any): Promise<T>;
29
+ }
@@ -0,0 +1,138 @@
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 { Child } from "ibridge-flex";
11
+ import { createClient } from '@supabase/supabase-js';
12
+ import { RimoriClient } from "./RimoriClient";
13
+ export class PluginController {
14
+ constructor() {
15
+ this.onceListeners = new Map();
16
+ this.listeners = new Map();
17
+ this.communicationSecret = null;
18
+ this.initialized = false;
19
+ this.supabase = null;
20
+ this.supabaseInfo = null;
21
+ // localStorage.debug = "*";
22
+ this.plugin = new Child({
23
+ triggerChild: ({ topic, data, _id }) => {
24
+ var _a, _b;
25
+ // console.log("trigger child with topic:" + topic + " and data: ", data);
26
+ (_a = this.onceListeners.get(topic)) === null || _a === void 0 ? void 0 : _a.forEach((callback) => callback(_id, data));
27
+ this.onceListeners.set(topic, []);
28
+ (_b = this.listeners.get(topic)) === null || _b === void 0 ? void 0 : _b.forEach((callback) => callback(_id, data));
29
+ }
30
+ });
31
+ this.emit = this.emit.bind(this);
32
+ this.onOnce = this.onOnce.bind(this);
33
+ this.getClient = this.getClient.bind(this);
34
+ this.subscribe = this.subscribe.bind(this);
35
+ this.internalEmit = this.internalEmit.bind(this);
36
+ this.request = this.request.bind(this);
37
+ }
38
+ static getInstance() {
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ if (!PluginController.instance) {
41
+ PluginController.instance = new PluginController();
42
+ yield PluginController.instance.init();
43
+ PluginController.client = yield RimoriClient.getInstance(PluginController.instance);
44
+ }
45
+ return PluginController.client;
46
+ });
47
+ }
48
+ init() {
49
+ return __awaiter(this, void 0, void 0, function* () {
50
+ if (this.initialized)
51
+ return;
52
+ // Wait for the plugin to be ready
53
+ yield this.plugin.handshake().then(() => this.initialized = true).catch((error) => {
54
+ console.error("Failed to initialize the plugin communication:", error);
55
+ });
56
+ });
57
+ }
58
+ getSecret() {
59
+ if (!this.communicationSecret) {
60
+ const secret = new URLSearchParams(window.location.search).get("secret");
61
+ if (!secret) {
62
+ throw new Error("Communication secret not found in URL as query parameter");
63
+ }
64
+ this.communicationSecret = secret;
65
+ }
66
+ return this.communicationSecret;
67
+ }
68
+ getClient() {
69
+ return __awaiter(this, void 0, void 0, function* () {
70
+ if (this.supabase &&
71
+ this.supabaseInfo &&
72
+ this.supabaseInfo.expiration > new Date()) {
73
+ return { supabase: this.supabase, tablePrefix: this.supabaseInfo.tablePrefix, pluginId: this.supabaseInfo.pluginId };
74
+ }
75
+ this.supabaseInfo = yield this.request("getSupabaseAccess");
76
+ this.supabase = createClient(this.supabaseInfo.url, this.supabaseInfo.key, {
77
+ accessToken: () => Promise.resolve(this.getToken())
78
+ });
79
+ return { supabase: this.supabase, tablePrefix: this.supabaseInfo.tablePrefix, pluginId: this.supabaseInfo.pluginId };
80
+ });
81
+ }
82
+ getToken() {
83
+ return __awaiter(this, void 0, void 0, function* () {
84
+ if (this.supabaseInfo && this.supabaseInfo.expiration && this.supabaseInfo.expiration > new Date()) {
85
+ return this.supabaseInfo.token;
86
+ }
87
+ const response = yield this.request("getSupabaseAccess");
88
+ if (!this.supabaseInfo) {
89
+ throw new Error("Supabase info not found");
90
+ }
91
+ this.supabaseInfo.token = response.token;
92
+ this.supabaseInfo.expiration = response.expiration;
93
+ return this.supabaseInfo.token;
94
+ });
95
+ }
96
+ getSupabaseUrl() {
97
+ if (!this.supabaseInfo) {
98
+ throw new Error("Supabase info not found");
99
+ }
100
+ return this.supabaseInfo.url;
101
+ }
102
+ emit(eventName, data) {
103
+ this.internalEmit(eventName, 0, data);
104
+ }
105
+ // the communication needs to have an id to be able to distinguish between different responses
106
+ internalEmit(eventName, id, data) {
107
+ this.init().then(() => this.plugin.emitToParent(eventName, { data, _id: id, secret: this.getSecret() }));
108
+ }
109
+ subscribe(eventName, callback) {
110
+ var _a;
111
+ if (!this.listeners.has(eventName)) {
112
+ this.listeners.set(eventName, []);
113
+ }
114
+ (_a = this.listeners.get(eventName)) === null || _a === void 0 ? void 0 : _a.push(callback);
115
+ }
116
+ onOnce(eventName, callback) {
117
+ var _a;
118
+ if (!this.onceListeners.has(eventName)) {
119
+ this.onceListeners.set(eventName, []);
120
+ }
121
+ (_a = this.onceListeners.get(eventName)) === null || _a === void 0 ? void 0 : _a.push(callback);
122
+ }
123
+ request(topic_1) {
124
+ return __awaiter(this, arguments, void 0, function* (topic, data = {}) {
125
+ return yield new Promise((resolve) => {
126
+ let triggered = false;
127
+ const id = Math.random();
128
+ this.internalEmit(topic, id, data);
129
+ this.subscribe(topic, (_id, data) => {
130
+ if (triggered || (_id !== id && _id !== 0))
131
+ return;
132
+ triggered = true;
133
+ resolve(data);
134
+ });
135
+ });
136
+ });
137
+ }
138
+ }
@@ -0,0 +1,91 @@
1
+ import { PluginController } from "./PluginController";
2
+ import { SupabaseClient } from "@supabase/supabase-js";
3
+ import { GenericSchema } from "@supabase/supabase-js/dist/module/lib/types";
4
+ import { PostgrestQueryBuilder, PostgrestFilterBuilder } from "@supabase/postgrest-js";
5
+ import { BasicAssignment } from "../controller/SharedContentController";
6
+ import { Message, Tool, OnLLMResponse } from "../controller/AIController";
7
+ import { ObjectRequest } from "../controller/ObjectController";
8
+ export declare class RimoriClient {
9
+ private static instance;
10
+ private superbase;
11
+ private plugin;
12
+ functions: SupabaseClient["functions"];
13
+ storage: SupabaseClient["storage"];
14
+ pluginId: string;
15
+ tablePrefix: string;
16
+ private settingsController;
17
+ private sharedContentController;
18
+ private constructor();
19
+ static getInstance(pluginController: PluginController): Promise<RimoriClient>;
20
+ from<TableName extends string & keyof GenericSchema['Tables'], Table extends GenericSchema['Tables'][TableName]>(relation: TableName): PostgrestQueryBuilder<GenericSchema, Table, TableName>;
21
+ from<ViewName extends string & keyof GenericSchema['Views'], View extends GenericSchema['Views'][ViewName]>(relation: ViewName): PostgrestQueryBuilder<GenericSchema, View, ViewName>;
22
+ /**
23
+ * Perform a function call.
24
+ *
25
+ * @param functionName - The function name to call
26
+ * @param args - The arguments to pass to the function call
27
+ * @param options - Named parameters
28
+ * @param options.head - When set to `true`, `data` will not be returned.
29
+ * Useful if you only need the count.
30
+ * @param options.get - When set to `true`, the function will be called with
31
+ * read-only access mode.
32
+ * @param options.count - Count algorithm to use to count rows returned by the
33
+ * function. Only applicable for [set-returning
34
+ * functions](https://www.postgresql.org/docs/current/functions-srf.html).
35
+ *
36
+ * `"exact"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the
37
+ * hood.
38
+ *
39
+ * `"planned"`: Approximated but fast count algorithm. Uses the Postgres
40
+ * statistics under the hood.
41
+ *
42
+ * `"estimated"`: Uses exact count for low numbers and planned count for high
43
+ * numbers.
44
+ */
45
+ rpc<Fn extends GenericSchema['Functions'][string], FnName extends string & keyof GenericSchema['Functions']>(functionName: FnName, args?: Fn['Args'], options?: {
46
+ head?: boolean;
47
+ get?: boolean;
48
+ count?: 'exact' | 'planned' | 'estimated';
49
+ }): PostgrestFilterBuilder<GenericSchema, Fn['Returns'] extends any[] ? Fn['Returns'][number] extends Record<string, unknown> ? Fn['Returns'][number] : never : never, Fn['Returns'], string, null>;
50
+ private getTableName;
51
+ subscribe(eventName: string, callback: (_id: number, data: any) => void): void;
52
+ request<T>(eventName: string, data?: any): Promise<T>;
53
+ emit(eventName: string, data: any): void;
54
+ /**
55
+ * Get the settings for the plugin. T can be any type of settings, UserSettings or SystemSettings.
56
+ * @param defaultSettings The default settings to use if no settings are found.
57
+ * @param genericSettings The type of settings to get.
58
+ * @returns The settings for the plugin.
59
+ */
60
+ getSettings<T extends object>(defaultSettings: T, genericSettings?: "user" | "system"): Promise<T>;
61
+ setSettings(settings: any, genericSettings?: "user" | "system"): Promise<void>;
62
+ getAIResponse(messages: Message[], tools?: Tool[]): Promise<string>;
63
+ getAIResponseStream(messages: Message[], onMessage: OnLLMResponse, tools?: Tool[]): Promise<void>;
64
+ getVoiceResponse(text: string, voice?: string, speed?: number, language?: string): Promise<Blob>;
65
+ getVoiceToTextResponse(file: Blob): Promise<string>;
66
+ generateObject(request: ObjectRequest): Promise<any>;
67
+ /**
68
+ * Fetch new shared content.
69
+ * @param type The type of shared content to fetch. E.g. assignments, exercises, etc.
70
+ * @param generatorInstructions The instructions for the generator.
71
+ * @param filter The filter for the shared content.
72
+ * @returns The new shared content.
73
+ */
74
+ fetchNewSharedContent<T, R = T & BasicAssignment>(type: string, generatorInstructions: (reservedTopics: string[]) => Promise<ObjectRequest> | ObjectRequest, filter?: {
75
+ column: string;
76
+ value: string | number | boolean;
77
+ }): Promise<R[]>;
78
+ /**
79
+ * Get a shared content item by id.
80
+ * @param type The type of shared content to get. E.g. assignments, exercises, etc.
81
+ * @param id The id of the shared content item.
82
+ * @returns The shared content item.
83
+ */
84
+ getSharedContent<T extends BasicAssignment>(type: string, id: string): Promise<T>;
85
+ /**
86
+ * Complete a shared content item.
87
+ * @param type The type of shared content to complete. E.g. assignments, exercises, etc.
88
+ * @param assignmentId The id of the shared content item to complete.
89
+ */
90
+ completeSharedContent(type: string, assignmentId: string): Promise<void>;
91
+ }
@@ -0,0 +1,163 @@
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 { SettingsController } from "../controller/SettingsController";
11
+ import { getSTTResponse, getTTSResponse } from "../controller/VoiceController";
12
+ import { SharedContentController } from "../controller/SharedContentController";
13
+ import { streamChatGPT, generateText } from "../controller/AIController";
14
+ import { generateObject as generateObjectFunction } from "../controller/ObjectController";
15
+ export class RimoriClient {
16
+ constructor(options) {
17
+ this.superbase = options.supabase;
18
+ this.pluginId = options.pluginId;
19
+ this.plugin = options.pluginController;
20
+ this.tablePrefix = options.tablePrefix;
21
+ this.storage = this.superbase.storage;
22
+ this.functions = this.superbase.functions;
23
+ this.settingsController = new SettingsController(options.supabase, options.pluginId);
24
+ this.sharedContentController = new SharedContentController(this);
25
+ this.rpc = this.rpc.bind(this);
26
+ this.from = this.from.bind(this);
27
+ this.emit = this.emit.bind(this);
28
+ this.request = this.request.bind(this);
29
+ this.subscribe = this.subscribe.bind(this);
30
+ this.getSettings = this.getSettings.bind(this);
31
+ this.setSettings = this.setSettings.bind(this);
32
+ this.getAIResponse = this.getAIResponse.bind(this);
33
+ this.generateObject = this.generateObject.bind(this);
34
+ this.getVoiceResponse = this.getVoiceResponse.bind(this);
35
+ this.getAIResponseStream = this.getAIResponseStream.bind(this);
36
+ this.getVoiceToTextResponse = this.getVoiceToTextResponse.bind(this);
37
+ }
38
+ static getInstance(pluginController) {
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ if (!RimoriClient.instance) {
41
+ const { supabase, tablePrefix, pluginId } = yield pluginController.getClient();
42
+ RimoriClient.instance = new RimoriClient({ pluginController, supabase, tablePrefix, pluginId });
43
+ }
44
+ return RimoriClient.instance;
45
+ });
46
+ }
47
+ from(relation) {
48
+ return this.superbase.from(this.getTableName(relation));
49
+ }
50
+ /**
51
+ * Perform a function call.
52
+ *
53
+ * @param functionName - The function name to call
54
+ * @param args - The arguments to pass to the function call
55
+ * @param options - Named parameters
56
+ * @param options.head - When set to `true`, `data` will not be returned.
57
+ * Useful if you only need the count.
58
+ * @param options.get - When set to `true`, the function will be called with
59
+ * read-only access mode.
60
+ * @param options.count - Count algorithm to use to count rows returned by the
61
+ * function. Only applicable for [set-returning
62
+ * functions](https://www.postgresql.org/docs/current/functions-srf.html).
63
+ *
64
+ * `"exact"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the
65
+ * hood.
66
+ *
67
+ * `"planned"`: Approximated but fast count algorithm. Uses the Postgres
68
+ * statistics under the hood.
69
+ *
70
+ * `"estimated"`: Uses exact count for low numbers and planned count for high
71
+ * numbers.
72
+ */
73
+ rpc(functionName, args = {}, options = {}) {
74
+ return this.superbase.rpc(this.getTableName(functionName), args, options);
75
+ }
76
+ getTableName(type) {
77
+ return this.tablePrefix + "_" + type;
78
+ }
79
+ subscribe(eventName, callback) {
80
+ this.plugin.subscribe(eventName, callback);
81
+ }
82
+ request(eventName, data) {
83
+ return this.plugin.request(eventName, data);
84
+ }
85
+ emit(eventName, data) {
86
+ this.plugin.emit(eventName, data);
87
+ }
88
+ /**
89
+ * Get the settings for the plugin. T can be any type of settings, UserSettings or SystemSettings.
90
+ * @param defaultSettings The default settings to use if no settings are found.
91
+ * @param genericSettings The type of settings to get.
92
+ * @returns The settings for the plugin.
93
+ */
94
+ getSettings(defaultSettings, genericSettings) {
95
+ return __awaiter(this, void 0, void 0, function* () {
96
+ return this.settingsController.getSettings(defaultSettings, genericSettings);
97
+ });
98
+ }
99
+ setSettings(settings, genericSettings) {
100
+ return __awaiter(this, void 0, void 0, function* () {
101
+ yield this.settingsController.setSettings(settings, genericSettings);
102
+ });
103
+ }
104
+ getAIResponse(messages, tools) {
105
+ return __awaiter(this, void 0, void 0, function* () {
106
+ const token = yield this.plugin.getToken();
107
+ return generateText(messages, tools || [], token).then(response => response.messages[0].content[0].text);
108
+ });
109
+ }
110
+ getAIResponseStream(messages, onMessage, tools) {
111
+ return __awaiter(this, void 0, void 0, function* () {
112
+ const token = yield this.plugin.getToken();
113
+ streamChatGPT(messages, tools || [], onMessage, token);
114
+ });
115
+ }
116
+ getVoiceResponse(text_1) {
117
+ return __awaiter(this, arguments, void 0, function* (text, voice = "alloy", speed = 1, language) {
118
+ return getTTSResponse(this.plugin.getSupabaseUrl(), { input: text, voice, speed, language }, yield this.plugin.getToken());
119
+ });
120
+ }
121
+ getVoiceToTextResponse(file) {
122
+ return getSTTResponse(this.superbase, file);
123
+ }
124
+ generateObject(request) {
125
+ return __awaiter(this, void 0, void 0, function* () {
126
+ const token = yield this.plugin.getToken();
127
+ return generateObjectFunction(request, token);
128
+ });
129
+ }
130
+ /**
131
+ * Fetch new shared content.
132
+ * @param type The type of shared content to fetch. E.g. assignments, exercises, etc.
133
+ * @param generatorInstructions The instructions for the generator.
134
+ * @param filter The filter for the shared content.
135
+ * @returns The new shared content.
136
+ */
137
+ fetchNewSharedContent(type, generatorInstructions, filter) {
138
+ return __awaiter(this, void 0, void 0, function* () {
139
+ return this.sharedContentController.fetchNewSharedContent(type, generatorInstructions, filter);
140
+ });
141
+ }
142
+ /**
143
+ * Get a shared content item by id.
144
+ * @param type The type of shared content to get. E.g. assignments, exercises, etc.
145
+ * @param id The id of the shared content item.
146
+ * @returns The shared content item.
147
+ */
148
+ getSharedContent(type, id) {
149
+ return __awaiter(this, void 0, void 0, function* () {
150
+ return this.sharedContentController.getSharedContent(type, id);
151
+ });
152
+ }
153
+ /**
154
+ * Complete a shared content item.
155
+ * @param type The type of shared content to complete. E.g. assignments, exercises, etc.
156
+ * @param assignmentId The id of the shared content item to complete.
157
+ */
158
+ completeSharedContent(type, assignmentId) {
159
+ return __awaiter(this, void 0, void 0, function* () {
160
+ return this.sharedContentController.completeSharedContent(type, assignmentId);
161
+ });
162
+ }
163
+ }
@@ -0,0 +1,13 @@
1
+ import { SupabaseClient } from "@supabase/supabase-js";
2
+ declare class SettingsController {
3
+ private static instance;
4
+ private supabase;
5
+ private tablePrefix;
6
+ private constructor();
7
+ static getInstance(): SettingsController;
8
+ initialize(supabase: SupabaseClient, tablePrefix: string): void;
9
+ getSettings<T>(defaultSettings: T, genericSettings?: "user" | "system"): Promise<T>;
10
+ setSettings(settings: any, genericSettings?: "user" | "system"): Promise<void>;
11
+ }
12
+ export declare const settingsController: SettingsController;
13
+ export {};
@@ -0,0 +1,55 @@
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
+ class SettingsController {
11
+ constructor() {
12
+ this.supabase = null;
13
+ this.tablePrefix = '';
14
+ }
15
+ static getInstance() {
16
+ if (!SettingsController.instance) {
17
+ SettingsController.instance = new SettingsController();
18
+ }
19
+ return SettingsController.instance;
20
+ }
21
+ initialize(supabase, tablePrefix) {
22
+ this.supabase = supabase;
23
+ this.tablePrefix = tablePrefix;
24
+ }
25
+ getSettings(defaultSettings, genericSettings) {
26
+ return __awaiter(this, void 0, void 0, function* () {
27
+ // async function getPluginSettings(supabase:SupabaseClient, genericSettings:string) {
28
+ const response = yield this.plugin.request("get_settings", { genericSettings });
29
+ if (response === null) {
30
+ this.setSettings(defaultSettings, genericSettings);
31
+ return defaultSettings;
32
+ //if the settings are not the same, merge the settings
33
+ }
34
+ else if (Object.keys(response).length !== Object.keys(defaultSettings).length) {
35
+ const existingKeys = Object.fromEntries(Object.entries(response).filter(([k]) => k in defaultSettings));
36
+ const mergedSettings = Object.assign(Object.assign({}, defaultSettings), existingKeys);
37
+ console.warn("Settings mismatch", { response, defaultSettings, mergedSettings });
38
+ this.setSettings(mergedSettings, genericSettings);
39
+ return mergedSettings;
40
+ }
41
+ return response;
42
+ });
43
+ }
44
+ setSettings(settings, genericSettings) {
45
+ return __awaiter(this, void 0, void 0, function* () {
46
+ if (!this.supabase) {
47
+ throw new Error("SettingsController not initialized");
48
+ }
49
+ yield this.supabase
50
+ .from(this.tablePrefix + '_settings')
51
+ .upsert(settings);
52
+ });
53
+ }
54
+ }
55
+ export const settingsController = SettingsController.getInstance();
@@ -0,0 +1 @@
1
+ export declare function setTheme(): void;
@@ -0,0 +1,13 @@
1
+ export function setTheme() {
2
+ const urlParams = new URLSearchParams(window.location.search);
3
+ let theme = urlParams.get('theme');
4
+ const isSidebar = urlParams.get('applicationMode') === "sidebar";
5
+ if (!theme || theme === 'system') {
6
+ theme = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
7
+ }
8
+ document.documentElement.classList.add("dark:text-gray-200", "bg-white");
9
+ if (theme === 'dark') {
10
+ document.documentElement.classList.add('dark', isSidebar ? "bg-gray-920" : "bg-gray-950");
11
+ document.documentElement.style.background = isSidebar ? "rgb(6, 12, 30)" : "rgb(3, 7, 18)";
12
+ }
13
+ }
@@ -0,0 +1,2 @@
1
+ export declare function getSTTResponse(audio: Blob): Promise<any>;
2
+ export declare function getTTSResponse(text: string, voice: string, speed: number, language?: string): Promise<Blob>;
@@ -0,0 +1,27 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ export function getSTTResponse(audio) {
11
+ return __awaiter(this, void 0, void 0, function* () {
12
+ const formData = new FormData();
13
+ formData.append('file', audio);
14
+ return yield fetch('/api/stt', { method: 'POST', body: formData })
15
+ .then(r => r.json())
16
+ .then(r => r.text);
17
+ });
18
+ }
19
+ export function getTTSResponse(text, voice, speed, language) {
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ return yield fetch('/api/speech', {
22
+ method: 'POST',
23
+ headers: { 'Content-Type': 'application/json' },
24
+ body: JSON.stringify({ input: text, voice, speed, language }),
25
+ }).then(r => r.blob());
26
+ });
27
+ }
@@ -0,0 +1,11 @@
1
+ type Listener<T = any> = (event: T) => void;
2
+ export declare class EventEmitter {
3
+ private events;
4
+ constructor();
5
+ on<T = any>(eventName: string, listener: Listener<T>): void;
6
+ once<T = any>(eventName: string, listener: Listener<T>): void;
7
+ removeListener<T = any>(eventName: string, listener: Listener<T>): void;
8
+ emit<T = any>(eventName: string, data?: T): void;
9
+ }
10
+ export declare const EmitterSingleton: EventEmitter;
11
+ export {};
@@ -0,0 +1,41 @@
1
+ export class EventEmitter {
2
+ constructor() {
3
+ this.events = new Map();
4
+ this.on = this.on.bind(this);
5
+ this.once = this.once.bind(this);
6
+ this.emit = this.emit.bind(this);
7
+ this.removeListener = this.removeListener.bind(this);
8
+ }
9
+ // Subscribe to an event
10
+ on(eventName, listener) {
11
+ if (!this.events.has(eventName)) {
12
+ this.events.set(eventName, []);
13
+ }
14
+ this.events.get(eventName).push(listener);
15
+ }
16
+ // Subscribe to an event for a single invocation
17
+ once(eventName, listener) {
18
+ const onceWrapper = (event) => {
19
+ this.removeListener(eventName, onceWrapper);
20
+ listener(event);
21
+ };
22
+ this.on(eventName, onceWrapper);
23
+ }
24
+ // Remove a specific listener
25
+ removeListener(eventName, listener) {
26
+ const listeners = this.events.get(eventName);
27
+ if (!listeners)
28
+ return;
29
+ this.events.set(eventName, listeners.filter((l) => l !== listener));
30
+ }
31
+ // Emit an event
32
+ emit(eventName, data) {
33
+ const listeners = this.events.get(eventName);
34
+ console.log("emit", eventName, data, listeners);
35
+ if (!listeners)
36
+ return;
37
+ listeners.forEach((listener) => listener(data));
38
+ }
39
+ }
40
+ const emitter = new EventEmitter();
41
+ export const EmitterSingleton = emitter;
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ import { EventEmitter } from "./EventEmitter";
3
+ export declare const EventEmitterProvider: React.FC<{
4
+ children: React.ReactNode;
5
+ }>;
6
+ export declare const useEventEmitter: () => EventEmitter;
@@ -0,0 +1,19 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createContext, useContext, useRef } from "react";
4
+ import { EmitterSingleton } from "./EventEmitter";
5
+ // Create the Context
6
+ const EventEmitterContext = createContext(null);
7
+ // Provider Component
8
+ export const EventEmitterProvider = ({ children }) => {
9
+ const eventEmitterRef = useRef(EmitterSingleton);
10
+ return (_jsx(EventEmitterContext.Provider, { value: eventEmitterRef.current, children: children }));
11
+ };
12
+ // Hook to use the EventEmitter
13
+ export const useEventEmitter = () => {
14
+ const context = useContext(EventEmitterContext);
15
+ if (!context) {
16
+ throw new Error("useEventEmitter must be used within an EventEmitterProvider");
17
+ }
18
+ return context;
19
+ };
@@ -0,0 +1,8 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { RimoriClient } from '../plugin/RimoriClient';
3
+ interface PluginProviderProps {
4
+ children: ReactNode;
5
+ }
6
+ export declare const PluginProvider: React.FC<PluginProviderProps>;
7
+ export declare const usePlugin: () => RimoriClient;
8
+ export {};