Skip to content

Commit 7d31bec

Browse files
lethemanhlethemanh
authored andcommitted
fix: Avoid insert empty api key when creating openrag assistant 🐛
1 parent 89ecca5 commit 7d31bec

File tree

4 files changed

+202
-62
lines changed

4 files changed

+202
-62
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
[cozy-client](../README.md) / [models](../modules/models.md) / [assistant](../modules/models.assistant.md) / Assistant
2+
3+
# Interface: Assistant<>
4+
5+
[models](../modules/models.md).[assistant](../modules/models.assistant.md).Assistant
6+
7+
## Properties
8+
9+
### apiKey
10+
11+
**apiKey**: `string`
12+
13+
API key for authentication
14+
15+
*Defined in*
16+
17+
[packages/cozy-client/src/models/assistant.js:17](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/assistant.js#L17)
18+
19+
***
20+
21+
### baseUrl
22+
23+
**baseUrl**: `string`
24+
25+
Provider's base URL
26+
27+
*Defined in*
28+
29+
[packages/cozy-client/src/models/assistant.js:16](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/assistant.js#L16)
30+
31+
***
32+
33+
### icon
34+
35+
**icon**: `string`
36+
37+
Optional icon for the assistant
38+
39+
*Defined in*
40+
41+
[packages/cozy-client/src/models/assistant.js:13](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/assistant.js#L13)
42+
43+
***
44+
45+
### isCustomModel
46+
47+
**isCustomModel**: `boolean`
48+
49+
Indicates if it's a custom model
50+
51+
*Defined in*
52+
53+
[packages/cozy-client/src/models/assistant.js:14](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/assistant.js#L14)
54+
55+
***
56+
57+
### model
58+
59+
**model**: `string`
60+
61+
Model identifier
62+
63+
*Defined in*
64+
65+
[packages/cozy-client/src/models/assistant.js:15](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/assistant.js#L15)
66+
67+
***
68+
69+
### name
70+
71+
**name**: `string`
72+
73+
Name of the assistant
74+
75+
*Defined in*
76+
77+
[packages/cozy-client/src/models/assistant.js:11](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/assistant.js#L11)
78+
79+
***
80+
81+
### prompt
82+
83+
**prompt**: `string`
84+
85+
Prompt for the assistant
86+
87+
*Defined in*
88+
89+
[packages/cozy-client/src/models/assistant.js:12](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/assistant.js#L12)
90+
91+
***
92+
93+
### providerId
94+
95+
**providerId**: `string`
96+
97+
ID of the provider
98+
99+
*Defined in*
100+
101+
[packages/cozy-client/src/models/assistant.js:18](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/models/assistant.js#L18)

docs/api/cozy-client/modules/models.assistant.md

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44

55
[models](models.md).assistant
66

7+
## Interfaces
8+
9+
* [Assistant](../interfaces/models.assistant.Assistant.md)
10+
711
## Functions
812

913
### createAssistant
@@ -19,14 +23,7 @@ Creates a new assistant with the provided data.
1923
| Name | Type | Description |
2024
| :------ | :------ | :------ |
2125
| `client` | [`CozyClient`](../classes/CozyClient.md) | An instance of CozyClient |
22-
| `assistantData` | `Object` | Data for the new assistant |
23-
| `assistantData.apiKey` | `string` | API key for authentication |
24-
| `assistantData.baseUrl` | `string` | Provider's base URL |
25-
| `assistantData.icon` | `string` | - |
26-
| `assistantData.isCustomModel` | `boolean` | Indicates if it's a custom model |
27-
| `assistantData.model` | `string` | Model identifier |
28-
| `assistantData.name` | `string` | Name of the assistant |
29-
| `assistantData.prompt` | `string` | Prompt for the assistant |
26+
| `assistantData` | [`Assistant`](../interfaces/models.assistant.Assistant.md) | Data for the new assistant |
3027

3128
*Returns*
3229

@@ -36,7 +33,7 @@ Creates a new assistant with the provided data.
3633

3734
*Defined in*
3835

39-
[packages/cozy-client/src/models/assistant.js:20](https://github.com/linagora/cozy-client/blob/master/packages/cozy-client/src/models/assistant.js#L20)
36+
[packages/cozy-client/src/models/assistant.js:29](https://github.com/linagora/cozy-client/blob/master/packages/cozy-client/src/models/assistant.js#L29)
4037

4138
***
4239

@@ -63,7 +60,7 @@ Deletes an assistant by its ID.
6360

6461
*Defined in*
6562

66-
[packages/cozy-client/src/models/assistant.js:79](https://github.com/linagora/cozy-client/blob/master/packages/cozy-client/src/models/assistant.js#L79)
63+
[packages/cozy-client/src/models/assistant.js:99](https://github.com/linagora/cozy-client/blob/master/packages/cozy-client/src/models/assistant.js#L99)
6764

6865
***
6966

@@ -81,14 +78,7 @@ Edit assistant with the provided data.
8178
| :------ | :------ | :------ |
8279
| `client` | [`CozyClient`](../classes/CozyClient.md) | An instance of CozyClient |
8380
| `assistantId` | `string` | ID of existed assistant |
84-
| `assistantData` | `Object` | Data for the new assistant |
85-
| `assistantData.apiKey` | `string` | - |
86-
| `assistantData.baseUrl` | `string` | Provider's base URL |
87-
| `assistantData.icon` | `string` | - |
88-
| `assistantData.isCustomModel` | `boolean` | Indicates if it's a custom model |
89-
| `assistantData.model` | `string` | Model identifier |
90-
| `assistantData.name` | `string` | Name of the assistant |
91-
| `assistantData.prompt` | `string` | Prompt for the assistant |
81+
| `assistantData` | [`Assistant`](../interfaces/models.assistant.Assistant.md) | Data for the editted assistant |
9282

9383
*Returns*
9484

@@ -98,4 +88,4 @@ Edit assistant with the provided data.
9888

9989
*Defined in*
10090

101-
[packages/cozy-client/src/models/assistant.js:120](https://github.com/linagora/cozy-client/blob/master/packages/cozy-client/src/models/assistant.js#L120)
91+
[packages/cozy-client/src/models/assistant.js:133](https://github.com/linagora/cozy-client/blob/master/packages/cozy-client/src/models/assistant.js#L133)

packages/cozy-client/src/models/assistant.js

Lines changed: 61 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,51 @@ import CozyClient from '../CozyClient'
22
import { Q } from '../queries/dsl'
33
import logger from '../logger'
44

5+
const ASSISTANT_DOCTYPE = 'io.cozy.ai.chat.assistants'
6+
const ACCOUNT_DOCTYPE = 'io.cozy.accounts'
7+
const OPENRAG_MODEL = 'openrag'
8+
9+
/**
10+
* @typedef {object} Assistant
11+
* @property {string} name - Name of the assistant
12+
* @property {string} prompt - Prompt for the assistant
13+
* @property {string} [icon] - Optional icon for the assistant
14+
* @property {boolean} isCustomModel - Indicates if it's a custom model
15+
* @property {string} model - Model identifier
16+
* @property {string} baseUrl - Provider's base URL
17+
* @property {string} [apiKey] - API key for authentication
18+
* @property {string} providerId - ID of the provider
19+
*/
20+
521
/**
622
* Creates a new assistant with the provided data.
723
*
824
* @param {CozyClient} client - An instance of CozyClient
9-
* @param {object} assistantData - Data for the new assistant
10-
* @param {string} assistantData.name - Name of the assistant
11-
* @param {string} assistantData.prompt - Prompt for the assistant
12-
* @param {string} [assistantData.icon] - Optional icon for the assistant
13-
* @param {boolean} assistantData.isCustomModel - Indicates if it's a custom model
14-
* @param {string} assistantData.model - Model identifier
15-
* @param {string} assistantData.baseUrl - Provider's base URL
16-
* @param {string} assistantData.apiKey - API key for authentication
25+
* @param {Assistant} assistantData - Data for the new assistant
1726
* @returns {Promise<void>} - A promise that resolves when the assistant is created
1827
* @throws {Error} - Throws an error if the creation fails
1928
*/
2029
export const createAssistant = async (client, assistantData) => {
2130
let createdAccountId = null
2231
try {
32+
if (!assistantData.apiKey && assistantData.model !== OPENRAG_MODEL) {
33+
throw new Error('API key is empty')
34+
}
35+
2336
const account = {
24-
_type: 'io.cozy.accounts',
37+
_type: ACCOUNT_DOCTYPE,
2538
auth: {
26-
login: assistantData.model,
27-
password: assistantData.apiKey
28-
},
29-
data: {
39+
login: assistantData.model
40+
}
41+
}
42+
if (assistantData.model !== OPENRAG_MODEL) {
43+
account.data = {
3044
baseUrl: assistantData.baseUrl
3145
}
3246
}
47+
if (assistantData.apiKey) {
48+
account.auth.password = assistantData.apiKey
49+
}
3350
const response = await client.save(account)
3451

3552
if (!response.data || !response.data._id) {
@@ -38,16 +55,19 @@ export const createAssistant = async (client, assistantData) => {
3855
createdAccountId = response.data._id
3956

4057
const assistant = {
41-
_type: 'io.cozy.ai.chat.assistants',
58+
_type: ASSISTANT_DOCTYPE,
4259
name: assistantData.name,
4360
prompt: assistantData.prompt,
4461
icon: assistantData.icon || null,
4562
isCustomModel: assistantData.isCustomModel,
4663
relationships: {
4764
provider: {
4865
data: {
49-
_type: 'io.cozy.accounts',
50-
_id: createdAccountId
66+
_type: ACCOUNT_DOCTYPE,
67+
_id: createdAccountId,
68+
metadata: {
69+
providerId: assistantData.providerId
70+
}
5171
}
5272
}
5373
}
@@ -79,7 +99,7 @@ export const createAssistant = async (client, assistantData) => {
7999
export const deleteAssistant = async (client, assistantId) => {
80100
try {
81101
const existedAssistant = await client.query(
82-
Q('io.cozy.ai.chat.assistants')
102+
Q(ASSISTANT_DOCTYPE)
83103
.getById(assistantId)
84104
.include(['provider'])
85105
)
@@ -88,12 +108,12 @@ export const deleteAssistant = async (client, assistantId) => {
88108
const provider = existedAssistant.included?.[0]
89109

90110
await client.stackClient
91-
.collection('io.cozy.ai.chat.assistants')
111+
.collection(ASSISTANT_DOCTYPE)
92112
.destroy({ _id: assistantId, _rev: assistantInstance._rev })
93113

94114
if (provider?._id && provider?._rev) {
95115
await client.stackClient
96-
.collection('io.cozy.accounts')
116+
.collection(ACCOUNT_DOCTYPE)
97117
.destroy({ _id: provider._id, _rev: provider._rev })
98118
}
99119
} catch (error) {
@@ -106,21 +126,14 @@ export const deleteAssistant = async (client, assistantId) => {
106126
*
107127
* @param {CozyClient} client - An instance of CozyClient
108128
* @param {string} assistantId - ID of existed assistant
109-
* @param {object} assistantData - Data for the new assistant
110-
* @param {string} assistantData.name - Name of the assistant
111-
* @param {string} assistantData.prompt - Prompt for the assistant
112-
* @param {string} [assistantData.icon] - Optional icon for the assistant
113-
* @param {boolean} assistantData.isCustomModel - Indicates if it's a custom model
114-
* @param {string} assistantData.model - Model identifier
115-
* @param {string} assistantData.baseUrl - Provider's base URL
116-
* @param {string} [assistantData.apiKey] - API key for authentication
129+
* @param {Assistant} assistantData - Data for the editted assistant
117130
* @returns {Promise<void>} - A promise that resolves when the assistant is edited
118131
* @throws {Error} - Throws an error if the edition fails
119132
*/
120133
export const editAssistant = async (client, assistantId, assistantData) => {
121134
try {
122135
const existedAssistant = await client.query(
123-
Q('io.cozy.ai.chat.assistants')
136+
Q(ASSISTANT_DOCTYPE)
124137
.getById(assistantId)
125138
.include(['provider'])
126139
)
@@ -147,9 +160,15 @@ export const editAssistant = async (client, assistantId, assistantData) => {
147160
baseUrl: assistantData.baseUrl
148161
}
149162
}
150-
if (assistantData.apiKey) {
163+
// Only update the password if a new API key is explicitly provided
164+
// and the model requires one. A missing key means keep the existing one.
165+
if (assistantData.apiKey && assistantData.model !== OPENRAG_MODEL) {
151166
account.auth.password = assistantData.apiKey
152167
}
168+
if (assistantData.model === OPENRAG_MODEL) {
169+
delete account.data?.baseUrl
170+
delete account.auth?.password
171+
}
153172
const response = await client.save(account)
154173

155174
if (!response.data || !response.data._id) {
@@ -161,7 +180,19 @@ export const editAssistant = async (client, assistantId, assistantData) => {
161180
name: assistantData.name,
162181
prompt: assistantData.prompt,
163182
icon: assistantData.icon || null,
164-
isCustomModel: assistantData.isCustomModel
183+
isCustomModel: assistantData.isCustomModel,
184+
relationships: {
185+
provider: {
186+
data: {
187+
...(existedAssistantData?.relationships?.provider?.data || {}),
188+
metadata: {
189+
...(existedAssistantData?.relationships?.provider?.data
190+
?.metadata || {}),
191+
providerId: assistantData.providerId
192+
}
193+
}
194+
}
195+
}
165196
}
166197
await client.save(assistant)
167198
} catch (error) {
Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,38 @@
1-
export function createAssistant(client: CozyClient, assistantData: {
2-
name: string;
3-
prompt: string;
4-
icon: string;
5-
isCustomModel: boolean;
6-
model: string;
7-
baseUrl: string;
8-
apiKey: string;
9-
}): Promise<void>;
1+
export function createAssistant(client: CozyClient, assistantData: Assistant): Promise<void>;
102
export function deleteAssistant(client: CozyClient, assistantId: string): Promise<void>;
11-
export function editAssistant(client: CozyClient, assistantId: string, assistantData: {
3+
export function editAssistant(client: CozyClient, assistantId: string, assistantData: Assistant): Promise<void>;
4+
export type Assistant = {
5+
/**
6+
* - Name of the assistant
7+
*/
128
name: string;
9+
/**
10+
* - Prompt for the assistant
11+
*/
1312
prompt: string;
14-
icon: string;
13+
/**
14+
* - Optional icon for the assistant
15+
*/
16+
icon?: string;
17+
/**
18+
* - Indicates if it's a custom model
19+
*/
1520
isCustomModel: boolean;
21+
/**
22+
* - Model identifier
23+
*/
1624
model: string;
25+
/**
26+
* - Provider's base URL
27+
*/
1728
baseUrl: string;
18-
apiKey: string;
19-
}): Promise<void>;
29+
/**
30+
* - API key for authentication
31+
*/
32+
apiKey?: string;
33+
/**
34+
* - ID of the provider
35+
*/
36+
providerId: string;
37+
};
2038
import CozyClient from "../CozyClient";

0 commit comments

Comments
 (0)