cozy-client 60.30.0 → 60.30.6
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.
- package/dist/CozyClient.js +2 -2
- package/dist/models/assistant.js +89 -78
- package/dist/models/assistant.spec.js +187 -0
- package/package.json +2 -2
- package/types/CozyClient.d.ts +1 -1
- package/types/models/assistant.d.ts +5 -0
package/dist/CozyClient.js
CHANGED
|
@@ -2025,7 +2025,7 @@ var CozyClient = /*#__PURE__*/function () {
|
|
|
2025
2025
|
* Resolves relationships on a document.
|
|
2026
2026
|
*
|
|
2027
2027
|
* The original document is kept in the target attribute of
|
|
2028
|
-
* the relationship
|
|
2028
|
+
* the relationship.
|
|
2029
2029
|
*
|
|
2030
2030
|
* @param {import("./types").CozyClientDocument} document - for which relationships must be resolved
|
|
2031
2031
|
* @param {Schema} [schemaArg] - The schema describing the relationships
|
|
@@ -3126,7 +3126,7 @@ var CozyClient = /*#__PURE__*/function () {
|
|
|
3126
3126
|
CozyClient.hooks = CozyClient.hooks || {};
|
|
3127
3127
|
CozyClient.fetchPolicies = _policies.default; //COZY_CLIENT_VERSION_PACKAGE in replaced by babel. See babel config
|
|
3128
3128
|
|
|
3129
|
-
CozyClient.version = "60.30.
|
|
3129
|
+
CozyClient.version = "60.30.6";
|
|
3130
3130
|
|
|
3131
3131
|
_microee.default.mixin(CozyClient);
|
|
3132
3132
|
|
package/dist/models/assistant.js
CHANGED
|
@@ -7,12 +7,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
});
|
|
8
8
|
exports.editAssistant = exports.deleteAssistant = exports.createAssistant = void 0;
|
|
9
9
|
|
|
10
|
-
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
11
|
-
|
|
12
10
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
13
11
|
|
|
14
12
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
15
13
|
|
|
14
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
15
|
+
|
|
16
|
+
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
17
|
+
|
|
16
18
|
var _CozyClient = _interopRequireDefault(require("../CozyClient"));
|
|
17
19
|
|
|
18
20
|
var _dsl = require("../queries/dsl");
|
|
@@ -34,8 +36,53 @@ var ACCOUNT_DOCTYPE = 'io.cozy.accounts';
|
|
|
34
36
|
* @property {string} baseUrl - Provider's base URL
|
|
35
37
|
* @property {string} [apiKey] - API key for authentication
|
|
36
38
|
* @property {string} providerId - ID of the provider
|
|
39
|
+
* @property {string} [providerName] - Display name of the provider, used to
|
|
40
|
+
* name the account. Defaults to the provider id.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Builds the io.cozy.accounts document backing an assistant.
|
|
45
|
+
*
|
|
46
|
+
* `auth` is the only part the stack encrypts, so it holds the API key alone.
|
|
47
|
+
* The model and base URL are configuration and live in `data`, where they map
|
|
48
|
+
* onto the stack's `llm_override`. `identifier` points at `accountName` so the
|
|
49
|
+
* account is labelled after its provider rather than after `auth.login`.
|
|
50
|
+
*
|
|
51
|
+
* @param {Assistant} assistantData - Data for the assistant
|
|
52
|
+
* @param {object} [provider] - Existing provider account to update
|
|
53
|
+
* @returns {object} The io.cozy.accounts document to save
|
|
37
54
|
*/
|
|
38
55
|
|
|
56
|
+
var buildProviderAccount = function buildProviderAccount(assistantData, provider) {
|
|
57
|
+
// `login` used to hold the model: dropped so it stops being encrypted with
|
|
58
|
+
// the API key, and stops outranking `accountName` as the label.
|
|
59
|
+
var _ref = (provider === null || provider === void 0 ? void 0 : provider.auth) || {},
|
|
60
|
+
login = _ref.login,
|
|
61
|
+
password = _ref.password,
|
|
62
|
+
auth = (0, _objectWithoutProperties2.default)(_ref, ["login", "password"]);
|
|
63
|
+
|
|
64
|
+
var _ref2 = (provider === null || provider === void 0 ? void 0 : provider.data) || {},
|
|
65
|
+
baseUrl = _ref2.baseUrl,
|
|
66
|
+
data = (0, _objectWithoutProperties2.default)(_ref2, ["baseUrl"]); // No new key means keeping the one the stack holds in `credentials_encrypted`.
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
var apiKey = assistantData.apiKey || (assistantData.baseUrl ? password : undefined);
|
|
70
|
+
return _objectSpread(_objectSpread({}, provider), {}, {
|
|
71
|
+
_type: ACCOUNT_DOCTYPE,
|
|
72
|
+
account_type: assistantData.providerId,
|
|
73
|
+
identifier: 'accountName',
|
|
74
|
+
auth: _objectSpread(_objectSpread({}, auth), {}, {
|
|
75
|
+
accountName: assistantData.providerName || assistantData.providerId
|
|
76
|
+
}, apiKey ? {
|
|
77
|
+
password: apiKey
|
|
78
|
+
} : {}),
|
|
79
|
+
data: _objectSpread(_objectSpread({}, data), {}, {
|
|
80
|
+
model: assistantData.model
|
|
81
|
+
}, assistantData.baseUrl ? {
|
|
82
|
+
baseUrl: assistantData.baseUrl
|
|
83
|
+
} : {})
|
|
84
|
+
});
|
|
85
|
+
};
|
|
39
86
|
/**
|
|
40
87
|
* Creates a new assistant with the provided data.
|
|
41
88
|
*
|
|
@@ -45,8 +92,9 @@ var ACCOUNT_DOCTYPE = 'io.cozy.accounts';
|
|
|
45
92
|
* @throws {Error} - Throws an error if the creation fails
|
|
46
93
|
*/
|
|
47
94
|
|
|
95
|
+
|
|
48
96
|
var createAssistant = /*#__PURE__*/function () {
|
|
49
|
-
var
|
|
97
|
+
var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client, assistantData) {
|
|
50
98
|
var createdAccountId, account, response, assistant, _yield$client$save, savedAssistant;
|
|
51
99
|
|
|
52
100
|
return _regenerator.default.wrap(function _callee$(_context) {
|
|
@@ -55,38 +103,21 @@ var createAssistant = /*#__PURE__*/function () {
|
|
|
55
103
|
case 0:
|
|
56
104
|
createdAccountId = null;
|
|
57
105
|
_context.prev = 1;
|
|
58
|
-
account =
|
|
59
|
-
|
|
60
|
-
auth: {
|
|
61
|
-
login: assistantData.model
|
|
62
|
-
},
|
|
63
|
-
account_type: assistantData.providerId
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
if (assistantData.baseUrl) {
|
|
67
|
-
account.data = {
|
|
68
|
-
baseUrl: assistantData.baseUrl
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (assistantData.apiKey) {
|
|
73
|
-
account.auth.password = assistantData.apiKey;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
_context.next = 7;
|
|
106
|
+
account = buildProviderAccount(assistantData);
|
|
107
|
+
_context.next = 5;
|
|
77
108
|
return client.save(account);
|
|
78
109
|
|
|
79
|
-
case
|
|
110
|
+
case 5:
|
|
80
111
|
response = _context.sent;
|
|
81
112
|
|
|
82
113
|
if (!(!response.data || !response.data._id)) {
|
|
83
|
-
_context.next =
|
|
114
|
+
_context.next = 8;
|
|
84
115
|
break;
|
|
85
116
|
}
|
|
86
117
|
|
|
87
118
|
throw new Error('Failed to create account for assistant');
|
|
88
119
|
|
|
89
|
-
case
|
|
120
|
+
case 8:
|
|
90
121
|
createdAccountId = response.data._id;
|
|
91
122
|
assistant = {
|
|
92
123
|
_type: ASSISTANT_DOCTYPE,
|
|
@@ -105,52 +136,52 @@ var createAssistant = /*#__PURE__*/function () {
|
|
|
105
136
|
}
|
|
106
137
|
}
|
|
107
138
|
};
|
|
108
|
-
_context.next =
|
|
139
|
+
_context.next = 12;
|
|
109
140
|
return client.save(assistant);
|
|
110
141
|
|
|
111
|
-
case
|
|
142
|
+
case 12:
|
|
112
143
|
_yield$client$save = _context.sent;
|
|
113
144
|
savedAssistant = _yield$client$save.data;
|
|
114
145
|
return _context.abrupt("return", savedAssistant);
|
|
115
146
|
|
|
116
|
-
case
|
|
117
|
-
_context.prev =
|
|
147
|
+
case 17:
|
|
148
|
+
_context.prev = 17;
|
|
118
149
|
_context.t0 = _context["catch"](1);
|
|
119
150
|
|
|
120
151
|
if (!createdAccountId) {
|
|
121
|
-
_context.next =
|
|
152
|
+
_context.next = 28;
|
|
122
153
|
break;
|
|
123
154
|
}
|
|
124
155
|
|
|
125
|
-
_context.prev =
|
|
126
|
-
_context.next =
|
|
156
|
+
_context.prev = 20;
|
|
157
|
+
_context.next = 23;
|
|
127
158
|
return client.stackClient.collection('io.cozy.accounts').destroy({
|
|
128
159
|
_id: createdAccountId
|
|
129
160
|
});
|
|
130
161
|
|
|
131
|
-
case
|
|
132
|
-
_context.next =
|
|
162
|
+
case 23:
|
|
163
|
+
_context.next = 28;
|
|
133
164
|
break;
|
|
134
165
|
|
|
135
|
-
case
|
|
136
|
-
_context.prev =
|
|
137
|
-
_context.t1 = _context["catch"](
|
|
166
|
+
case 25:
|
|
167
|
+
_context.prev = 25;
|
|
168
|
+
_context.t1 = _context["catch"](20);
|
|
138
169
|
|
|
139
170
|
_logger.default.warn('Failed to cleanup orphaned account:', _context.t1);
|
|
140
171
|
|
|
141
|
-
case
|
|
172
|
+
case 28:
|
|
142
173
|
throw new Error("Failed to create assistant: ".concat(_context.t0.message));
|
|
143
174
|
|
|
144
|
-
case
|
|
175
|
+
case 29:
|
|
145
176
|
case "end":
|
|
146
177
|
return _context.stop();
|
|
147
178
|
}
|
|
148
179
|
}
|
|
149
|
-
}, _callee, null, [[1,
|
|
180
|
+
}, _callee, null, [[1, 17], [20, 25]]);
|
|
150
181
|
}));
|
|
151
182
|
|
|
152
183
|
return function createAssistant(_x, _x2) {
|
|
153
|
-
return
|
|
184
|
+
return _ref3.apply(this, arguments);
|
|
154
185
|
};
|
|
155
186
|
}();
|
|
156
187
|
/**
|
|
@@ -166,7 +197,7 @@ var createAssistant = /*#__PURE__*/function () {
|
|
|
166
197
|
exports.createAssistant = createAssistant;
|
|
167
198
|
|
|
168
199
|
var deleteAssistant = /*#__PURE__*/function () {
|
|
169
|
-
var
|
|
200
|
+
var _ref4 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(client, assistantId) {
|
|
170
201
|
var _yield$client$query, assistantDoc, included, provider;
|
|
171
202
|
|
|
172
203
|
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
@@ -213,7 +244,7 @@ var deleteAssistant = /*#__PURE__*/function () {
|
|
|
213
244
|
}));
|
|
214
245
|
|
|
215
246
|
return function deleteAssistant(_x3, _x4) {
|
|
216
|
-
return
|
|
247
|
+
return _ref4.apply(this, arguments);
|
|
217
248
|
};
|
|
218
249
|
}();
|
|
219
250
|
/**
|
|
@@ -230,8 +261,8 @@ var deleteAssistant = /*#__PURE__*/function () {
|
|
|
230
261
|
exports.deleteAssistant = deleteAssistant;
|
|
231
262
|
|
|
232
263
|
var editAssistant = /*#__PURE__*/function () {
|
|
233
|
-
var
|
|
234
|
-
var _existedAssistant$inc, _existedAssistantData, _existedAssistantData2, _existedAssistantData3, _existedAssistantData4, _existedAssistantData5, existedAssistant, existedAssistantData, provider, account,
|
|
264
|
+
var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(client, assistantId, assistantData) {
|
|
265
|
+
var _existedAssistant$inc, _existedAssistantData, _existedAssistantData2, _existedAssistantData3, _existedAssistantData4, _existedAssistantData5, existedAssistant, existedAssistantData, provider, account, response, assistant;
|
|
235
266
|
|
|
236
267
|
return _regenerator.default.wrap(function _callee3$(_context3) {
|
|
237
268
|
while (1) {
|
|
@@ -263,41 +294,21 @@ var editAssistant = /*#__PURE__*/function () {
|
|
|
263
294
|
throw new Error('Provider account not found for assistant');
|
|
264
295
|
|
|
265
296
|
case 10:
|
|
266
|
-
account =
|
|
267
|
-
|
|
268
|
-
login: assistantData.model
|
|
269
|
-
}),
|
|
270
|
-
account_type: assistantData.providerId,
|
|
271
|
-
data: _objectSpread({}, provider.data || {})
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
if (assistantData.baseUrl) {
|
|
275
|
-
account.data.baseUrl = assistantData.baseUrl;
|
|
276
|
-
} else {
|
|
277
|
-
(_account$data = account.data) === null || _account$data === void 0 ? true : delete _account$data.baseUrl;
|
|
278
|
-
} // Only update the password if a new API key is explicitly provided
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
if (assistantData.apiKey) {
|
|
282
|
-
account.auth.password = assistantData.apiKey;
|
|
283
|
-
} else if (!assistantData.baseUrl) {
|
|
284
|
-
(_account$auth = account.auth) === null || _account$auth === void 0 ? true : delete _account$auth.password;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
_context3.next = 15;
|
|
297
|
+
account = buildProviderAccount(assistantData, provider);
|
|
298
|
+
_context3.next = 13;
|
|
288
299
|
return client.save(account);
|
|
289
300
|
|
|
290
|
-
case
|
|
301
|
+
case 13:
|
|
291
302
|
response = _context3.sent;
|
|
292
303
|
|
|
293
304
|
if (!(!response.data || !response.data._id)) {
|
|
294
|
-
_context3.next =
|
|
305
|
+
_context3.next = 16;
|
|
295
306
|
break;
|
|
296
307
|
}
|
|
297
308
|
|
|
298
309
|
throw new Error('Failed to edit account for assistant');
|
|
299
310
|
|
|
300
|
-
case
|
|
311
|
+
case 16:
|
|
301
312
|
assistant = _objectSpread(_objectSpread({}, existedAssistantData), {}, {
|
|
302
313
|
name: assistantData.name,
|
|
303
314
|
prompt: assistantData.prompt,
|
|
@@ -312,28 +323,28 @@ var editAssistant = /*#__PURE__*/function () {
|
|
|
312
323
|
}
|
|
313
324
|
}
|
|
314
325
|
});
|
|
315
|
-
_context3.next =
|
|
326
|
+
_context3.next = 19;
|
|
316
327
|
return client.save(assistant);
|
|
317
328
|
|
|
318
|
-
case
|
|
319
|
-
_context3.next =
|
|
329
|
+
case 19:
|
|
330
|
+
_context3.next = 24;
|
|
320
331
|
break;
|
|
321
332
|
|
|
322
|
-
case
|
|
323
|
-
_context3.prev =
|
|
333
|
+
case 21:
|
|
334
|
+
_context3.prev = 21;
|
|
324
335
|
_context3.t0 = _context3["catch"](0);
|
|
325
336
|
throw new Error("Failed to edit assistant: ".concat(_context3.t0.message));
|
|
326
337
|
|
|
327
|
-
case
|
|
338
|
+
case 24:
|
|
328
339
|
case "end":
|
|
329
340
|
return _context3.stop();
|
|
330
341
|
}
|
|
331
342
|
}
|
|
332
|
-
}, _callee3, null, [[0,
|
|
343
|
+
}, _callee3, null, [[0, 21]]);
|
|
333
344
|
}));
|
|
334
345
|
|
|
335
346
|
return function editAssistant(_x5, _x6, _x7) {
|
|
336
|
-
return
|
|
347
|
+
return _ref5.apply(this, arguments);
|
|
337
348
|
};
|
|
338
349
|
}();
|
|
339
350
|
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { createAssistant, editAssistant } from './assistant'
|
|
2
|
+
|
|
3
|
+
describe('assistant provider account', () => {
|
|
4
|
+
const assistantData = {
|
|
5
|
+
name: 'My agent',
|
|
6
|
+
prompt: 'Be helpful',
|
|
7
|
+
model: 'gemini-3-pro',
|
|
8
|
+
baseUrl: 'https://generativelanguage.googleapis.com/v1beta/openai/v1',
|
|
9
|
+
providerId: 'google',
|
|
10
|
+
providerName: 'Google'
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
describe('createAssistant', () => {
|
|
14
|
+
const buildClient = () => ({
|
|
15
|
+
save: jest
|
|
16
|
+
.fn()
|
|
17
|
+
.mockResolvedValue({ data: { _id: 'account-id', _type: 'whatever' } })
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it('stores the model as configuration, not as a credential', async () => {
|
|
21
|
+
const client = buildClient()
|
|
22
|
+
|
|
23
|
+
await createAssistant(client, assistantData)
|
|
24
|
+
|
|
25
|
+
const account = client.save.mock.calls[0][0]
|
|
26
|
+
expect(account.data.model).toBe('gemini-3-pro')
|
|
27
|
+
// A model in `auth` would be duplicated into `credentials_encrypted`.
|
|
28
|
+
expect(account.auth.login).toBeUndefined()
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('keeps the model next to the other llm_override fields', async () => {
|
|
32
|
+
const client = buildClient()
|
|
33
|
+
|
|
34
|
+
await createAssistant(client, { ...assistantData, apiKey: 'sk-1234' })
|
|
35
|
+
|
|
36
|
+
const account = client.save.mock.calls[0][0]
|
|
37
|
+
expect(account.data).toEqual({
|
|
38
|
+
model: 'gemini-3-pro',
|
|
39
|
+
baseUrl: 'https://generativelanguage.googleapis.com/v1beta/openai/v1'
|
|
40
|
+
})
|
|
41
|
+
expect(account.auth.password).toBe('sk-1234')
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('labels the account after the provider', async () => {
|
|
45
|
+
const client = buildClient()
|
|
46
|
+
|
|
47
|
+
await createAssistant(client, assistantData)
|
|
48
|
+
|
|
49
|
+
const account = client.save.mock.calls[0][0]
|
|
50
|
+
expect(account.identifier).toBe('accountName')
|
|
51
|
+
expect(account.auth.accountName).toBe('Google')
|
|
52
|
+
// `name` is computed by the stack from `auth[identifier]` on creation
|
|
53
|
+
expect(account.name).toBeUndefined()
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('falls back to the provider id when no display name is given', async () => {
|
|
57
|
+
const client = buildClient()
|
|
58
|
+
|
|
59
|
+
await createAssistant(client, {
|
|
60
|
+
...assistantData,
|
|
61
|
+
providerName: undefined
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
const account = client.save.mock.calls[0][0]
|
|
65
|
+
expect(account.auth.accountName).toBe('google')
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
describe('editAssistant', () => {
|
|
70
|
+
const buildClient = provider => ({
|
|
71
|
+
query: jest.fn().mockResolvedValue({
|
|
72
|
+
data: { _id: 'assistant-id', relationships: {} },
|
|
73
|
+
included: [provider]
|
|
74
|
+
}),
|
|
75
|
+
save: jest.fn().mockResolvedValue({ data: { _id: 'account-id' } })
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it('migrates an account that still holds the model in auth.login', async () => {
|
|
79
|
+
const client = buildClient({
|
|
80
|
+
_id: 'account-id',
|
|
81
|
+
auth: {
|
|
82
|
+
login: 'gemini-2.5-flash',
|
|
83
|
+
credentials_encrypted: 'encrypted-blob'
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
await editAssistant(client, 'assistant-id', assistantData)
|
|
88
|
+
|
|
89
|
+
const account = client.save.mock.calls[0][0]
|
|
90
|
+
expect(account.data.model).toBe('gemini-3-pro')
|
|
91
|
+
expect(account.auth.login).toBeUndefined()
|
|
92
|
+
// Left alone: the stack reads the API key from it, never the model.
|
|
93
|
+
expect(account.auth.credentials_encrypted).toBe('encrypted-blob')
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('relabels an account created before the naming fix', async () => {
|
|
97
|
+
const client = buildClient({
|
|
98
|
+
_id: 'account-id',
|
|
99
|
+
auth: { login: 'gemini-2.5-flash' }
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
await editAssistant(client, 'assistant-id', assistantData)
|
|
103
|
+
|
|
104
|
+
const account = client.save.mock.calls[0][0]
|
|
105
|
+
expect(account.identifier).toBe('accountName')
|
|
106
|
+
expect(account.auth.accountName).toBe('Google')
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
// Pre-existing coupling, pinned because the builder now expresses it once.
|
|
110
|
+
it('replaces the stored API key when a new one is given', async () => {
|
|
111
|
+
const client = buildClient({
|
|
112
|
+
_id: 'account-id',
|
|
113
|
+
auth: { accountName: 'Google', password: 'sk-old' }
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
await editAssistant(client, 'assistant-id', {
|
|
117
|
+
...assistantData,
|
|
118
|
+
apiKey: 'sk-new'
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
expect(client.save.mock.calls[0][0].auth.password).toBe('sk-new')
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
it('keeps the stored API key when only a baseUrl is given', async () => {
|
|
125
|
+
const client = buildClient({
|
|
126
|
+
_id: 'account-id',
|
|
127
|
+
auth: { accountName: 'Google', password: 'sk-old' }
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
await editAssistant(client, 'assistant-id', {
|
|
131
|
+
...assistantData,
|
|
132
|
+
apiKey: undefined
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
expect(client.save.mock.calls[0][0].auth.password).toBe('sk-old')
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
it('drops the stored API key when neither key nor baseUrl is given', async () => {
|
|
139
|
+
const client = buildClient({
|
|
140
|
+
_id: 'account-id',
|
|
141
|
+
auth: { accountName: 'Google', password: 'sk-old' }
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
await editAssistant(client, 'assistant-id', {
|
|
145
|
+
...assistantData,
|
|
146
|
+
apiKey: undefined,
|
|
147
|
+
baseUrl: undefined
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
const account = client.save.mock.calls[0][0]
|
|
151
|
+
expect(account.auth.password).toBeUndefined()
|
|
152
|
+
expect(account.data.baseUrl).toBeUndefined()
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
it('preserves the fields it does not own', async () => {
|
|
156
|
+
const client = buildClient({
|
|
157
|
+
_id: 'account-id',
|
|
158
|
+
_rev: '3-abc',
|
|
159
|
+
name: 'Google',
|
|
160
|
+
cozyMetadata: { createdAt: 'yesterday' },
|
|
161
|
+
auth: { accountName: 'Google', credentials_encrypted: 'blob' }
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
await editAssistant(client, 'assistant-id', assistantData)
|
|
165
|
+
|
|
166
|
+
const account = client.save.mock.calls[0][0]
|
|
167
|
+
expect(account._rev).toBe('3-abc')
|
|
168
|
+
expect(account.cozyMetadata).toEqual({ createdAt: 'yesterday' })
|
|
169
|
+
expect(account.auth.credentials_encrypted).toBe('blob')
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
it('updates the model of an already migrated account', async () => {
|
|
173
|
+
const client = buildClient({
|
|
174
|
+
_id: 'account-id',
|
|
175
|
+
identifier: 'accountName',
|
|
176
|
+
auth: { accountName: 'Google' },
|
|
177
|
+
data: { model: 'gemini-2.5-flash', baseUrl: 'https://example.org' }
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
await editAssistant(client, 'assistant-id', assistantData)
|
|
181
|
+
|
|
182
|
+
const account = client.save.mock.calls[0][0]
|
|
183
|
+
expect(account.data.model).toBe('gemini-3-pro')
|
|
184
|
+
expect(account.data.baseUrl).toBe(assistantData.baseUrl)
|
|
185
|
+
})
|
|
186
|
+
})
|
|
187
|
+
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-client",
|
|
3
|
-
"version": "60.30.
|
|
3
|
+
"version": "60.30.6",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/index.node.js",
|
|
6
6
|
"browser": "dist/index.js",
|
|
@@ -74,5 +74,5 @@
|
|
|
74
74
|
"react-native-ios11-devicecheck": "^0.0.3"
|
|
75
75
|
},
|
|
76
76
|
"sideEffects": false,
|
|
77
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "88101a3d13943828cd1cfcf39c40535c0a259afa"
|
|
78
78
|
}
|
package/types/CozyClient.d.ts
CHANGED
|
@@ -595,7 +595,7 @@ declare class CozyClient {
|
|
|
595
595
|
* Resolves relationships on a document.
|
|
596
596
|
*
|
|
597
597
|
* The original document is kept in the target attribute of
|
|
598
|
-
* the relationship
|
|
598
|
+
* the relationship.
|
|
599
599
|
*
|
|
600
600
|
* @param {import("./types").CozyClientDocument} document - for which relationships must be resolved
|
|
601
601
|
* @param {Schema} [schemaArg] - The schema describing the relationships
|
|
@@ -30,5 +30,10 @@ export type Assistant = {
|
|
|
30
30
|
* - ID of the provider
|
|
31
31
|
*/
|
|
32
32
|
providerId: string;
|
|
33
|
+
/**
|
|
34
|
+
* - Display name of the provider, used to
|
|
35
|
+
* name the account. Defaults to the provider id.
|
|
36
|
+
*/
|
|
37
|
+
providerName?: string;
|
|
33
38
|
};
|
|
34
39
|
import CozyClient from "../CozyClient";
|