@lobehub/chat 1.92.1 → 1.92.2

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.
@@ -168,6 +168,13 @@
168
168
  "when": 1748925630721,
169
169
  "tag": "0023_remove_param_and_doubao",
170
170
  "breakpoints": true
171
+ },
172
+ {
173
+ "idx": 24,
174
+ "version": "7",
175
+ "when": 1749301573666,
176
+ "tag": "0024_add_rbac_tables",
177
+ "breakpoints": true
171
178
  }
172
179
  ],
173
180
  "version": "6"
@@ -8,6 +8,7 @@ export * from './nextauth';
8
8
  export * from './oidc';
9
9
  export * from './rag';
10
10
  export * from './ragEvals';
11
+ export * from './rbac';
11
12
  export * from './relations';
12
13
  export * from './session';
13
14
  export * from './topic';
@@ -0,0 +1,82 @@
1
+ /* eslint-disable sort-keys-fix/sort-keys-fix */
2
+ import { boolean, index, integer, pgTable, primaryKey, text, timestamp } from 'drizzle-orm/pg-core';
3
+
4
+ import { timestamps } from './_helpers';
5
+ import { users } from './user';
6
+
7
+ // Roles table
8
+ export const roles = pgTable('rbac_roles', {
9
+ id: integer('id').primaryKey().generatedByDefaultAsIdentity(),
10
+ name: text('name').notNull().unique(), // Role name, e.g.: admin, user, guest
11
+ displayName: text('display_name').notNull(), // Display name
12
+ description: text('description'), // Role description
13
+ isSystem: boolean('is_system').default(false).notNull(), // Whether it's a system role
14
+ isActive: boolean('is_active').default(true).notNull(), // Whether it's active
15
+
16
+ ...timestamps,
17
+ });
18
+
19
+ export type NewRole = typeof roles.$inferInsert;
20
+ export type RoleItem = typeof roles.$inferSelect;
21
+
22
+ // Permissions table
23
+ export const permissions = pgTable('rbac_permissions', {
24
+ id: integer('id').primaryKey().generatedByDefaultAsIdentity(),
25
+ code: text('code').notNull().unique(), // Permission code, e.g.: chat:create, file:upload
26
+ name: text('name').notNull(), // Permission name
27
+ description: text('description'), // Permission description
28
+ category: text('category').notNull(), // Category it belongs to, e.g.: message, knowledge_base, agent
29
+ isActive: boolean('is_active').default(true).notNull(), // Whether it's active
30
+
31
+ ...timestamps,
32
+ });
33
+
34
+ export type NewPermission = typeof permissions.$inferInsert;
35
+ export type PermissionItem = typeof permissions.$inferSelect;
36
+
37
+ // Role-permission association table
38
+ export const rolePermissions = pgTable(
39
+ 'rbac_role_permissions',
40
+ {
41
+ roleId: integer('role_id')
42
+ .references(() => roles.id, { onDelete: 'cascade' })
43
+ .notNull(),
44
+ permissionId: integer('permission_id')
45
+ .references(() => permissions.id, { onDelete: 'cascade' })
46
+ .notNull(),
47
+
48
+ createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
49
+ },
50
+ (self) => [
51
+ primaryKey({ columns: [self.roleId, self.permissionId] }),
52
+ index('rbac_role_permissions_role_id_idx').on(self.roleId),
53
+ index('rbac_role_permissions_permission_id_idx').on(self.permissionId),
54
+ ],
55
+ );
56
+
57
+ export type NewRolePermission = typeof rolePermissions.$inferInsert;
58
+ export type RolePermissionItem = typeof rolePermissions.$inferSelect;
59
+
60
+ // User-role association table
61
+ export const userRoles = pgTable(
62
+ 'rbac_user_roles',
63
+ {
64
+ userId: text('user_id')
65
+ .references(() => users.id, { onDelete: 'cascade' })
66
+ .notNull(),
67
+ roleId: integer('role_id')
68
+ .references(() => roles.id, { onDelete: 'cascade' })
69
+ .notNull(),
70
+
71
+ createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
72
+ expiresAt: timestamp('expires_at', { withTimezone: true }), // Support for temporary roles
73
+ },
74
+ (self) => [
75
+ primaryKey({ columns: [self.userId, self.roleId] }),
76
+ index('rbac_user_roles_user_id_idx').on(self.userId),
77
+ index('rbac_user_roles_role_id_idx').on(self.roleId),
78
+ ],
79
+ );
80
+
81
+ export type NewUserRole = typeof userRoles.$inferInsert;
82
+ export type UserRoleItem = typeof userRoles.$inferSelect;
@@ -5,7 +5,14 @@ import { systemToUserModels } from '@/const/models';
5
5
 
6
6
  import { LobeRuntimeAI } from '../BaseAI';
7
7
  import { AgentRuntimeErrorType } from '../error';
8
- import { ChatMethodOptions, ChatStreamPayload, ModelProvider } from '../types';
8
+ import {
9
+ ChatMethodOptions,
10
+ ChatStreamPayload,
11
+ Embeddings,
12
+ EmbeddingsOptions,
13
+ EmbeddingsPayload,
14
+ ModelProvider,
15
+ } from '../types';
9
16
  import { AgentRuntimeError } from '../utils/createError';
10
17
  import { debugStream } from '../utils/debugStream';
11
18
  import { transformResponseToStream } from '../utils/openaiCompatibleFactory';
@@ -75,33 +82,50 @@ export class LobeAzureOpenAI implements LobeRuntimeAI {
75
82
  });
76
83
  }
77
84
  } catch (e) {
78
- let error = e as { [key: string]: any; code: string; message: string };
85
+ return this.handleError(e, model);
86
+ }
87
+ }
88
+
89
+ async embeddings(payload: EmbeddingsPayload, options?: EmbeddingsOptions): Promise<Embeddings[]> {
90
+ try {
91
+ const res = await this.client.embeddings.create(
92
+ { ...payload, encoding_format: 'float', user: options?.user },
93
+ { headers: options?.headers, signal: options?.signal },
94
+ );
95
+
96
+ return res.data.map((item) => item.embedding);
97
+ } catch (error) {
98
+ return this.handleError(error, payload.model);
99
+ }
100
+ }
101
+
102
+ protected handleError(e: any, model?: string): never {
103
+ let error = e as { [key: string]: any; code: string; message: string };
79
104
 
80
- if (error.code) {
81
- switch (error.code) {
82
- case 'DeploymentNotFound': {
83
- error = { ...error, deployId: model };
84
- }
105
+ if (error.code) {
106
+ switch (error.code) {
107
+ case 'DeploymentNotFound': {
108
+ error = { ...error, deployId: model };
85
109
  }
86
- } else {
87
- error = {
88
- cause: error.cause,
89
- message: error.message,
90
- name: error.name,
91
- } as any;
92
110
  }
111
+ } else {
112
+ error = {
113
+ cause: error.cause,
114
+ message: error.message,
115
+ name: error.name,
116
+ } as any;
117
+ }
93
118
 
94
- const errorType = error.code
95
- ? AgentRuntimeErrorType.ProviderBizError
96
- : AgentRuntimeErrorType.AgentRuntimeError;
119
+ const errorType = error.code
120
+ ? AgentRuntimeErrorType.ProviderBizError
121
+ : AgentRuntimeErrorType.AgentRuntimeError;
97
122
 
98
- throw AgentRuntimeError.chat({
99
- endpoint: this.maskSensitiveUrl(this.baseURL),
100
- error,
101
- errorType,
102
- provider: ModelProvider.Azure,
103
- });
104
- }
123
+ throw AgentRuntimeError.chat({
124
+ endpoint: this.maskSensitiveUrl(this.baseURL),
125
+ error,
126
+ errorType,
127
+ provider: ModelProvider.Azure,
128
+ });
105
129
  }
106
130
 
107
131
  // Convert object keys to camel case, copy from `@azure/openai` in `node_modules/@azure/openai/dist/index.cjs`