cozy-search 2.4.0 → 2.5.0
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/README.md +13 -6
- package/dist/components/KnowledgeBase/autoprovision.d.ts +5 -0
- package/dist/components/KnowledgeBase/autoprovision.js +100 -19
- package/dist/components/KnowledgeBase/autoprovision.spec.js +119 -35
- package/dist/components/KnowledgeBase/provisioning.d.ts +3 -1
- package/dist/components/KnowledgeBase/provisioning.js +123 -82
- package/dist/components/KnowledgeBase/provisioning.spec.js +52 -0
- package/dist/components/KnowledgeBase/ragIndexing.d.ts +3 -1
- package/dist/components/KnowledgeBase/ragIndexing.js +123 -65
- package/dist/components/KnowledgeBase/ragIndexing.spec.js +51 -0
- package/dist/components/KnowledgeBase/useRagIndexTriggers.d.ts +1 -0
- package/dist/components/KnowledgeBase/useRagIndexTriggers.js +27 -0
- package/dist/components/KnowledgeBase/useRagIndexTriggers.spec.d.ts +1 -0
- package/dist/components/KnowledgeBase/useRagIndexTriggers.spec.js +47 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +14 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -61,12 +61,19 @@ of verbs (cozy-home and cozy-drive use `ALL`).
|
|
|
61
61
|
|
|
62
62
|
Opening the assistant (`AssistantView` or `AssistantDialog`) calls
|
|
63
63
|
`autoprovisionAssistants(client)` once per session: when the
|
|
64
|
-
`cozy.assistant.autoprovision` flag lists assistants, it
|
|
65
|
-
`
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
64
|
+
`cozy.assistant.autoprovision` flag lists assistants, it makes sure the
|
|
65
|
+
`rag-index` triggers exist, gives the root folder to the assistants that
|
|
66
|
+
have no knowledge base folder, then runs
|
|
67
|
+
`ensureProvisionedAssistants(client, entries)`.
|
|
68
|
+
|
|
69
|
+
A host app should only call the `useRagIndexTriggers` hook (or
|
|
70
|
+
`ensureRagIndexTriggers(client)`) at startup: one request when the
|
|
71
|
+
triggers already exist, and the knowledge base folders get indexed as
|
|
72
|
+
they change before the assistant is ever opened. The assistants are
|
|
73
|
+
provisioned when the assistant opens; a host app that wants that earlier
|
|
74
|
+
can call `autoprovisionAssistants(client)` or the
|
|
75
|
+
`useAssistantsAutoprovision` hook. Every call shares the first one's
|
|
76
|
+
promise, the triggers step included, so nothing runs twice.
|
|
70
77
|
|
|
71
78
|
`setupRagIndexing(client)` makes sure the instance's two
|
|
72
79
|
`rag-index` triggers exist (one on `io.cozy.files`, one on
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
export function resetAutoprovisionForTests(): void;
|
|
2
|
+
export function autoprovisionEntries(): Array<object> | null;
|
|
3
|
+
export function ensureRagIndexTriggers(client: import("cozy-client").CozyClient): Promise<{
|
|
4
|
+
triggers: string[];
|
|
5
|
+
error: Error | null;
|
|
6
|
+
}>;
|
|
2
7
|
export function autoprovisionAssistants(client: import("cozy-client").CozyClient): Promise<null | {
|
|
3
8
|
setup: object;
|
|
4
9
|
created: string[];
|
|
@@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", {
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
|
-
exports.resetAutoprovisionForTests = exports.autoprovisionAssistants = void 0;
|
|
8
|
+
exports.resetAutoprovisionForTests = exports.ensureRagIndexTriggers = exports.autoprovisionEntries = exports.autoprovisionAssistants = void 0;
|
|
9
9
|
|
|
10
10
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
11
11
|
|
|
@@ -34,24 +34,70 @@ var warn = function warn() {
|
|
|
34
34
|
(_console = console).warn.apply(_console, ['cozy-search autoprovision:'].concat(args));
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
+
var triggersPending = null;
|
|
37
38
|
var pending = null;
|
|
38
39
|
|
|
39
40
|
var resetAutoprovisionForTests = function resetAutoprovisionForTests() {
|
|
41
|
+
triggersPending = null;
|
|
40
42
|
pending = null;
|
|
41
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* The entries of the autoprovision flag, or null when it lists nothing.
|
|
46
|
+
* @returns {Array<object>|null}
|
|
47
|
+
*/
|
|
48
|
+
|
|
42
49
|
|
|
43
50
|
exports.resetAutoprovisionForTests = resetAutoprovisionForTests;
|
|
44
51
|
|
|
52
|
+
var autoprovisionEntries = function autoprovisionEntries() {
|
|
53
|
+
var entries = (0, _cozyFlags.default)(_provisioning.AUTOPROVISION_FLAG);
|
|
54
|
+
return Array.isArray(entries) && entries.length > 0 ? entries : null;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Makes sure the instance has its rag-index triggers, so the files of the
|
|
58
|
+
* knowledge base folders get indexed as they change. Runs once per session
|
|
59
|
+
* and never rejects: a host app can call it at startup, it costs a single
|
|
60
|
+
* request when the triggers already exist.
|
|
61
|
+
* @param {import('cozy-client').CozyClient} client - The cozy client.
|
|
62
|
+
* @returns {Promise<{triggers: string[], error: Error|null}>} The
|
|
63
|
+
* `arguments` of the triggers created, and the failure if any.
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
exports.autoprovisionEntries = autoprovisionEntries;
|
|
68
|
+
|
|
69
|
+
var ensureRagIndexTriggers = function ensureRagIndexTriggers(client) {
|
|
70
|
+
if (!triggersPending) {
|
|
71
|
+
triggersPending = (0, _ragIndexing.createRagIndexTriggers)(client).then(function (triggers) {
|
|
72
|
+
return {
|
|
73
|
+
triggers: triggers,
|
|
74
|
+
error: null
|
|
75
|
+
};
|
|
76
|
+
}, function (error) {
|
|
77
|
+
warn('cannot set up the rag-index triggers', error);
|
|
78
|
+
return {
|
|
79
|
+
triggers: [],
|
|
80
|
+
error: error
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return triggersPending;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
exports.ensureRagIndexTriggers = ensureRagIndexTriggers;
|
|
89
|
+
|
|
45
90
|
var run = /*#__PURE__*/function () {
|
|
46
91
|
var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client) {
|
|
47
|
-
var entries, setup, result;
|
|
92
|
+
var entries, setup, _yield$ensureRagIndex, triggers, error, assistants, result;
|
|
93
|
+
|
|
48
94
|
return _regenerator.default.wrap(function _callee$(_context) {
|
|
49
95
|
while (1) {
|
|
50
96
|
switch (_context.prev = _context.next) {
|
|
51
97
|
case 0:
|
|
52
|
-
entries = (
|
|
98
|
+
entries = autoprovisionEntries();
|
|
53
99
|
|
|
54
|
-
if (
|
|
100
|
+
if (entries) {
|
|
55
101
|
_context.next = 3;
|
|
56
102
|
break;
|
|
57
103
|
}
|
|
@@ -59,15 +105,48 @@ var run = /*#__PURE__*/function () {
|
|
|
59
105
|
return _context.abrupt("return", null);
|
|
60
106
|
|
|
61
107
|
case 3:
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
_context.next =
|
|
68
|
-
return (
|
|
69
|
-
|
|
70
|
-
case
|
|
108
|
+
setup = {
|
|
109
|
+
triggers: [],
|
|
110
|
+
migrated: [],
|
|
111
|
+
errors: []
|
|
112
|
+
};
|
|
113
|
+
_context.next = 6;
|
|
114
|
+
return ensureRagIndexTriggers(client);
|
|
115
|
+
|
|
116
|
+
case 6:
|
|
117
|
+
_yield$ensureRagIndex = _context.sent;
|
|
118
|
+
triggers = _yield$ensureRagIndex.triggers;
|
|
119
|
+
error = _yield$ensureRagIndex.error;
|
|
120
|
+
setup.triggers = triggers;
|
|
121
|
+
if (error) setup.errors.push(error);
|
|
122
|
+
assistants = null;
|
|
123
|
+
_context.prev = 12;
|
|
124
|
+
_context.next = 15;
|
|
125
|
+
return (0, _ragIndexing.fetchAssistants)(client);
|
|
126
|
+
|
|
127
|
+
case 15:
|
|
128
|
+
assistants = _context.sent;
|
|
129
|
+
_context.next = 18;
|
|
130
|
+
return (0, _ragIndexing.migrateAssistantsWithoutFolder)(client, assistants);
|
|
131
|
+
|
|
132
|
+
case 18:
|
|
133
|
+
setup.migrated = _context.sent;
|
|
134
|
+
_context.next = 25;
|
|
135
|
+
break;
|
|
136
|
+
|
|
137
|
+
case 21:
|
|
138
|
+
_context.prev = 21;
|
|
139
|
+
_context.t0 = _context["catch"](12);
|
|
140
|
+
warn('cannot migrate the assistants without folder', _context.t0);
|
|
141
|
+
setup.errors.push(_context.t0);
|
|
142
|
+
|
|
143
|
+
case 25:
|
|
144
|
+
_context.next = 27;
|
|
145
|
+
return (0, _provisioning.ensureProvisionedAssistants)(client, entries, {
|
|
146
|
+
assistants: assistants
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
case 27:
|
|
71
150
|
result = _context.sent;
|
|
72
151
|
|
|
73
152
|
if (result.skipped.length > 0) {
|
|
@@ -78,12 +157,12 @@ var run = /*#__PURE__*/function () {
|
|
|
78
157
|
setup: setup
|
|
79
158
|
}, result));
|
|
80
159
|
|
|
81
|
-
case
|
|
160
|
+
case 30:
|
|
82
161
|
case "end":
|
|
83
162
|
return _context.stop();
|
|
84
163
|
}
|
|
85
164
|
}
|
|
86
|
-
}, _callee);
|
|
165
|
+
}, _callee, null, [[12, 21]]);
|
|
87
166
|
}));
|
|
88
167
|
|
|
89
168
|
return function run(_x) {
|
|
@@ -91,10 +170,12 @@ var run = /*#__PURE__*/function () {
|
|
|
91
170
|
};
|
|
92
171
|
}();
|
|
93
172
|
/**
|
|
94
|
-
* Sets up the rag-index triggers,
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
173
|
+
* Sets up the rag-index triggers, gives a folder to the assistants that
|
|
174
|
+
* lack one, then provisions the assistants listed in the autoprovision
|
|
175
|
+
* flag. Runs once per session: every call shares the first one's promise,
|
|
176
|
+
* and the triggers step is shared with ensureRagIndexTriggers, so a host
|
|
177
|
+
* app that ensured them at startup does not pay for them twice. Never
|
|
178
|
+
* rejects.
|
|
98
179
|
* @param {import('cozy-client').CozyClient} client - The cozy client.
|
|
99
180
|
* @returns {Promise<null|{setup: object, created: string[], ensured: string[], skipped: {id: string, reason: string}[]}>} Null when the flag lists nothing.
|
|
100
181
|
*/
|
|
@@ -2,59 +2,135 @@ import flag from 'cozy-flags'
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
autoprovisionAssistants,
|
|
5
|
+
autoprovisionEntries,
|
|
6
|
+
ensureRagIndexTriggers,
|
|
5
7
|
resetAutoprovisionForTests
|
|
6
8
|
} from './autoprovision'
|
|
7
9
|
import { ensureProvisionedAssistants } from './provisioning'
|
|
8
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
createRagIndexTriggers,
|
|
12
|
+
fetchAssistants,
|
|
13
|
+
migrateAssistantsWithoutFolder
|
|
14
|
+
} from './ragIndexing'
|
|
9
15
|
|
|
10
16
|
jest.mock('cozy-flags', () => jest.fn())
|
|
11
17
|
jest.mock('./provisioning', () => ({
|
|
12
18
|
AUTOPROVISION_FLAG: 'cozy.assistant.autoprovision',
|
|
13
19
|
ensureProvisionedAssistants: jest.fn()
|
|
14
20
|
}))
|
|
15
|
-
jest.mock('./ragIndexing', () => ({
|
|
21
|
+
jest.mock('./ragIndexing', () => ({
|
|
22
|
+
createRagIndexTriggers: jest.fn(),
|
|
23
|
+
fetchAssistants: jest.fn(),
|
|
24
|
+
migrateAssistantsWithoutFolder: jest.fn()
|
|
25
|
+
}))
|
|
16
26
|
|
|
17
27
|
const client = { id: 'client' }
|
|
18
28
|
const entries = [{ name: 'Docs', dirName: 'Docs' }]
|
|
29
|
+
const assistants = [{ _id: 'legacy' }]
|
|
19
30
|
let warnSpy
|
|
20
31
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
resetAutoprovisionForTests()
|
|
34
|
+
flag.mockReset()
|
|
35
|
+
warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {})
|
|
36
|
+
createRagIndexTriggers.mockReset().mockResolvedValue(['io.cozy.files'])
|
|
37
|
+
fetchAssistants.mockReset().mockResolvedValue(assistants)
|
|
38
|
+
migrateAssistantsWithoutFolder.mockReset().mockResolvedValue([])
|
|
39
|
+
ensureProvisionedAssistants
|
|
40
|
+
.mockReset()
|
|
41
|
+
.mockResolvedValue({ created: ['docs'], ensured: [], skipped: [] })
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
afterEach(() => {
|
|
45
|
+
warnSpy.mockRestore()
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
describe('autoprovisionEntries', () => {
|
|
49
|
+
it('returns the flag entries', () => {
|
|
50
|
+
flag.mockReturnValue(entries)
|
|
51
|
+
expect(autoprovisionEntries()).toBe(entries)
|
|
52
|
+
expect(flag).toHaveBeenCalledWith('cozy.assistant.autoprovision')
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it.each([null, undefined, [], 'docs', {}])('returns null for %p', value => {
|
|
56
|
+
flag.mockReturnValue(value)
|
|
57
|
+
expect(autoprovisionEntries()).toBeNull()
|
|
33
58
|
})
|
|
59
|
+
})
|
|
34
60
|
|
|
35
|
-
|
|
36
|
-
|
|
61
|
+
describe('ensureRagIndexTriggers', () => {
|
|
62
|
+
it('creates the missing triggers once per session', async () => {
|
|
63
|
+
const first = ensureRagIndexTriggers(client)
|
|
64
|
+
expect(ensureRagIndexTriggers(client)).toBe(first)
|
|
65
|
+
await expect(first).resolves.toEqual({
|
|
66
|
+
triggers: ['io.cozy.files'],
|
|
67
|
+
error: null
|
|
68
|
+
})
|
|
69
|
+
await ensureRagIndexTriggers(client)
|
|
70
|
+
|
|
71
|
+
expect(createRagIndexTriggers).toHaveBeenCalledTimes(1)
|
|
72
|
+
expect(createRagIndexTriggers).toHaveBeenCalledWith(client)
|
|
37
73
|
})
|
|
38
74
|
|
|
75
|
+
it('reports a failure without rejecting', async () => {
|
|
76
|
+
const error = new Error('forbidden')
|
|
77
|
+
createRagIndexTriggers.mockRejectedValue(error)
|
|
78
|
+
await expect(ensureRagIndexTriggers(client)).resolves.toEqual({
|
|
79
|
+
triggers: [],
|
|
80
|
+
error
|
|
81
|
+
})
|
|
82
|
+
expect(warnSpy).toHaveBeenCalledWith(
|
|
83
|
+
'cozy-search autoprovision:',
|
|
84
|
+
'cannot set up the rag-index triggers',
|
|
85
|
+
error
|
|
86
|
+
)
|
|
87
|
+
})
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
describe('autoprovisionAssistants', () => {
|
|
39
91
|
it('does nothing without flag entries', async () => {
|
|
40
92
|
flag.mockReturnValue(null)
|
|
41
93
|
await expect(autoprovisionAssistants(client)).resolves.toBeNull()
|
|
42
|
-
expect(
|
|
43
|
-
expect(
|
|
94
|
+
expect(createRagIndexTriggers).not.toHaveBeenCalled()
|
|
95
|
+
expect(fetchAssistants).not.toHaveBeenCalled()
|
|
96
|
+
expect(migrateAssistantsWithoutFolder).not.toHaveBeenCalled()
|
|
44
97
|
expect(ensureProvisionedAssistants).not.toHaveBeenCalled()
|
|
45
98
|
})
|
|
46
99
|
|
|
47
|
-
it('
|
|
100
|
+
it('lets the provisioning query the assistants when listing them failed', async () => {
|
|
101
|
+
flag.mockReturnValue(entries)
|
|
102
|
+
fetchAssistants.mockRejectedValue(new Error('nope'))
|
|
103
|
+
const result = await autoprovisionAssistants(client)
|
|
104
|
+
|
|
105
|
+
expect(migrateAssistantsWithoutFolder).not.toHaveBeenCalled()
|
|
106
|
+
expect(ensureProvisionedAssistants).toHaveBeenCalledWith(client, entries, {
|
|
107
|
+
assistants: null
|
|
108
|
+
})
|
|
109
|
+
expect(result.setup.errors.map(e => e.message)).toEqual(['nope'])
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
it('ensures the triggers, migrates, then provisions the flag entries', async () => {
|
|
48
113
|
flag.mockReturnValue(entries)
|
|
114
|
+
migrateAssistantsWithoutFolder.mockResolvedValue(['legacy'])
|
|
49
115
|
const result = await autoprovisionAssistants(client)
|
|
50
116
|
|
|
51
|
-
expect(
|
|
52
|
-
expect(
|
|
53
|
-
expect(
|
|
54
|
-
|
|
117
|
+
expect(createRagIndexTriggers).toHaveBeenCalledWith(client)
|
|
118
|
+
expect(fetchAssistants).toHaveBeenCalledTimes(1)
|
|
119
|
+
expect(migrateAssistantsWithoutFolder).toHaveBeenCalledWith(
|
|
120
|
+
client,
|
|
121
|
+
assistants
|
|
55
122
|
)
|
|
123
|
+
expect(ensureProvisionedAssistants).toHaveBeenCalledWith(client, entries, {
|
|
124
|
+
assistants
|
|
125
|
+
})
|
|
126
|
+
const order = [
|
|
127
|
+
createRagIndexTriggers,
|
|
128
|
+
migrateAssistantsWithoutFolder,
|
|
129
|
+
ensureProvisionedAssistants
|
|
130
|
+
].map(fn => fn.mock.invocationCallOrder[0])
|
|
131
|
+
expect(order).toEqual([...order].sort((a, b) => a - b))
|
|
56
132
|
expect(result).toEqual({
|
|
57
|
-
setup: { triggers: [], migrated: [], errors: [] },
|
|
133
|
+
setup: { triggers: ['io.cozy.files'], migrated: ['legacy'], errors: [] },
|
|
58
134
|
created: ['docs'],
|
|
59
135
|
ensured: [],
|
|
60
136
|
skipped: []
|
|
@@ -64,26 +140,34 @@ describe('autoprovisionAssistants', () => {
|
|
|
64
140
|
it('runs once per session, sharing the promise', async () => {
|
|
65
141
|
flag.mockReturnValue(entries)
|
|
66
142
|
const first = autoprovisionAssistants(client)
|
|
67
|
-
|
|
68
|
-
expect(second).toBe(first)
|
|
143
|
+
expect(autoprovisionAssistants(client)).toBe(first)
|
|
69
144
|
await first
|
|
70
145
|
await autoprovisionAssistants(client)
|
|
71
146
|
|
|
72
|
-
expect(
|
|
147
|
+
expect(createRagIndexTriggers).toHaveBeenCalledTimes(1)
|
|
73
148
|
expect(ensureProvisionedAssistants).toHaveBeenCalledTimes(1)
|
|
74
149
|
})
|
|
75
150
|
|
|
76
|
-
it('
|
|
151
|
+
it('shares the triggers step with ensureRagIndexTriggers', async () => {
|
|
77
152
|
flag.mockReturnValue(entries)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
153
|
+
await ensureRagIndexTriggers(client)
|
|
154
|
+
await autoprovisionAssistants(client)
|
|
155
|
+
|
|
156
|
+
expect(createRagIndexTriggers).toHaveBeenCalledTimes(1)
|
|
157
|
+
expect(ensureProvisionedAssistants).toHaveBeenCalledTimes(1)
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
it('still provisions when the setup steps failed', async () => {
|
|
161
|
+
flag.mockReturnValue(entries)
|
|
162
|
+
createRagIndexTriggers.mockRejectedValue(new Error('forbidden'))
|
|
163
|
+
migrateAssistantsWithoutFolder.mockRejectedValue(new Error('nope'))
|
|
83
164
|
const result = await autoprovisionAssistants(client)
|
|
84
165
|
|
|
85
166
|
expect(ensureProvisionedAssistants).toHaveBeenCalledTimes(1)
|
|
86
|
-
expect(result.setup.errors).
|
|
167
|
+
expect(result.setup.errors.map(e => e.message)).toEqual([
|
|
168
|
+
'forbidden',
|
|
169
|
+
'nope'
|
|
170
|
+
])
|
|
87
171
|
})
|
|
88
172
|
|
|
89
173
|
it('logs the skipped entries', async () => {
|
|
@@ -104,7 +188,7 @@ describe('autoprovisionAssistants', () => {
|
|
|
104
188
|
|
|
105
189
|
it('never rejects', async () => {
|
|
106
190
|
flag.mockReturnValue(entries)
|
|
107
|
-
|
|
191
|
+
ensureProvisionedAssistants.mockRejectedValue(new Error('boom'))
|
|
108
192
|
await expect(autoprovisionAssistants(client)).resolves.toBeNull()
|
|
109
193
|
expect(warnSpy).toHaveBeenCalledWith(
|
|
110
194
|
'cozy-search autoprovision:',
|
|
@@ -14,7 +14,9 @@ export function ensureProvisionedAssistants(client: import("cozy-client").CozyCl
|
|
|
14
14
|
prompt?: string;
|
|
15
15
|
icon?: string | null;
|
|
16
16
|
default?: boolean;
|
|
17
|
-
}
|
|
17
|
+
}>, { assistants }?: {
|
|
18
|
+
assistants?: object[] | undefined;
|
|
19
|
+
} | undefined): Promise<{
|
|
18
20
|
created: string[];
|
|
19
21
|
ensured: string[];
|
|
20
22
|
skipped: {
|