@rimori/client 2.5.19-next.1 → 2.5.19-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -49,6 +49,8 @@ export class Translator {
49
49
  },
50
50
  debug: false,
51
51
  parseMissingKeyHandler: (key, defaultValue) => {
52
+ if (!key.trim())
53
+ return '';
52
54
  if (this.isTranslationKey(key)) {
53
55
  console.warn(`Translation key not found: ${key}`);
54
56
  return defaultValue !== null && defaultValue !== void 0 ? defaultValue : '';
@@ -221,7 +221,7 @@ export class AIModule {
221
221
  }
222
222
  streamObject(params) {
223
223
  return __awaiter(this, void 0, void 0, function* () {
224
- var _a, _b, _c, _d;
224
+ var _a, _b, _c, _d, _e;
225
225
  const { messages, responseSchema, onResult = () => null, cache = false, tools = [], model = undefined, knowledgeId, } = params;
226
226
  const chatMessages = messages.map((message, index) => (Object.assign(Object.assign({}, message), { id: `${index + 1}` })));
227
227
  const response = yield fetch(`${this.backendUrl}/ai/llm`, {
@@ -253,6 +253,18 @@ export class AIModule {
253
253
  const reader = response.body.getReader();
254
254
  const decoder = new TextDecoder('utf-8');
255
255
  let currentObject = {};
256
+ // Buffer for SSE lines that are split across network chunks.
257
+ // TCP/IP does not guarantee that each `read()` call delivers a complete
258
+ // logical line. For example, the `token:` line carrying the session token
259
+ // may arrive as two separate chunks:
260
+ // chunk 1 → `token: {"token_id":`
261
+ // chunk 2 → `"abc123"}\n`
262
+ // Without buffering, `JSON.parse` would throw on the partial line and the
263
+ // session token would be silently discarded, causing the next LLM call to
264
+ // start without a session (triggering an unnecessary extra round-trip via
265
+ // `session.ensure()`). By keeping the incomplete tail in `lineBuffer` and
266
+ // prepending it to the next chunk we always process whole lines.
267
+ let lineBuffer = '';
256
268
  let isLoading = true;
257
269
  while (isLoading) {
258
270
  //wait 50ms to not overload the CPU
@@ -267,7 +279,13 @@ export class AIModule {
267
279
  if (!value)
268
280
  continue;
269
281
  const chunk = decoder.decode(value, { stream: true });
270
- const lines = chunk.split('\n').filter((line) => line.trim());
282
+ // Prepend any incomplete line left over from the previous chunk, then
283
+ // split on newlines. `parts.pop()` removes (and saves) the last element
284
+ // which may be an incomplete line if the chunk did not end with '\n'.
285
+ const combined = lineBuffer + chunk;
286
+ const parts = combined.split('\n');
287
+ lineBuffer = (_e = parts.pop()) !== null && _e !== void 0 ? _e : '';
288
+ const lines = parts.filter((line) => line.trim());
271
289
  for (const line of lines) {
272
290
  // Handle token: line (session token issued by backend on first AI call)
273
291
  if (line.startsWith('token:')) {
@@ -277,7 +295,7 @@ export class AIModule {
277
295
  this.sessionTokenId = tokenData.token_id;
278
296
  }
279
297
  }
280
- catch (_e) {
298
+ catch (_f) {
281
299
  console.error('Failed to parse token: line', line);
282
300
  }
283
301
  continue;
@@ -1,5 +1,40 @@
1
+ import { PostgrestQueryBuilder, PostgrestClientOptions } from '@supabase/postgrest-js';
1
2
  import { SupabaseClient } from '../CommunicationHandler';
2
3
  import { RimoriCommunicationHandler, RimoriInfo } from '../CommunicationHandler';
4
+ type GenericRelationship = {
5
+ foreignKeyName: string;
6
+ columns: string[];
7
+ isOneToOne?: boolean;
8
+ referencedRelation: string;
9
+ referencedColumns: string[];
10
+ };
11
+ type GenericTable = {
12
+ Row: Record<string, unknown>;
13
+ Insert: Record<string, unknown>;
14
+ Update: Record<string, unknown>;
15
+ Relationships: GenericRelationship[];
16
+ };
17
+ type GenericView = {
18
+ Row: Record<string, unknown>;
19
+ Relationships: GenericRelationship[];
20
+ };
21
+ type GenericSetofOption = {
22
+ isSetofReturn?: boolean;
23
+ isOneToOne?: boolean;
24
+ isNotNullable?: boolean;
25
+ to: string;
26
+ from: string;
27
+ };
28
+ type GenericFunction = {
29
+ Args: Record<string, unknown> | never;
30
+ Returns: unknown;
31
+ SetofOptions?: GenericSetofOption;
32
+ };
33
+ type GenericSchema = {
34
+ Tables: Record<string, GenericTable>;
35
+ Views: Record<string, GenericView>;
36
+ Functions: Record<string, GenericFunction>;
37
+ };
3
38
  /**
4
39
  * Database module for plugin database operations.
5
40
  * Provides access to plugin tables with automatic prefixing and schema management.
@@ -17,7 +52,7 @@ export declare class DbModule {
17
52
  * @param relation The table name (without prefix for plugin tables, with 'global_' for global tables).
18
53
  * @returns A Postgrest query builder for the table.
19
54
  */
20
- from(relation: string): import("@supabase/postgrest-js").PostgrestQueryBuilder<{} | import("@supabase/postgrest-js").PostgrestClientOptions, any, any, string, unknown>;
55
+ from<ViewName extends string & keyof GenericSchema['Views'], View extends GenericSchema['Views'][ViewName]>(relation: string): PostgrestQueryBuilder<PostgrestClientOptions, GenericSchema, GenericTable, ViewName, View>;
21
56
  /**
22
57
  * Get the table name for a given plugin table.
23
58
  * Internally all tables are prefixed with the plugin id. This function is used to get the correct table name for a given public table.
@@ -26,3 +61,4 @@ export declare class DbModule {
26
61
  */
27
62
  getTableName(table: string): string;
28
63
  }
64
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rimori/client",
3
- "version": "2.5.19-next.1",
3
+ "version": "2.5.19-next.3",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "repository": {