@@ -2,34 +2,51 @@ import CozyClient from '../CozyClient'
22import { Q } from '../queries/dsl'
33import 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 */
2029export 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) => {
7999export 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 */
120133export 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 ) {
0 commit comments