@christianriedl/utils 1.0.138 → 1.0.140
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/iOpenAI.d.ts +17 -8
- package/dist/types.d.ts +4 -2
- package/package.json +1 -1
- package/src/components/OpenAIConfig.vue +62 -31
- package/src/components/OpenAIMetaData.vue +55 -0
- package/src/components/SettingsLine.vue +20 -15
package/dist/iOpenAI.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { InjectionKey } from 'vue';
|
|
2
2
|
import { ILogger } from './iLogger';
|
|
3
|
-
import { Dictionary } from './types';
|
|
3
|
+
import { Dictionary, IDataItem, ItemType } from './types';
|
|
4
4
|
export declare const getOpenAISymbol: InjectionKey<() => IOpenAIService>;
|
|
5
5
|
export interface IResultAnnotation {
|
|
6
6
|
file_id?: string;
|
|
@@ -78,7 +78,7 @@ export interface IFunctionTool extends ITool {
|
|
|
78
78
|
export interface IComparisonFilter {
|
|
79
79
|
key: string;
|
|
80
80
|
type: 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte';
|
|
81
|
-
value:
|
|
81
|
+
value: ItemType;
|
|
82
82
|
}
|
|
83
83
|
export interface ICompoundFilter {
|
|
84
84
|
filters: IComparisonFilter[] | unknown;
|
|
@@ -112,17 +112,23 @@ export interface IOpenAIServiceWithTools extends IOpenAIService {
|
|
|
112
112
|
addFunctionTool(tool: IFunctionTool, toolFunction: ToolFunction): void;
|
|
113
113
|
getToolFunctions(tool: string): Promise<IResponseResult>;
|
|
114
114
|
}
|
|
115
|
+
export interface IVectorFile {
|
|
116
|
+
id: string;
|
|
117
|
+
filename: string;
|
|
118
|
+
attributes: Dictionary<ItemType> | null;
|
|
119
|
+
}
|
|
115
120
|
export interface IVectorStore {
|
|
116
121
|
id: string;
|
|
117
122
|
name: string;
|
|
118
|
-
|
|
123
|
+
metadata: Dictionary<string> | null;
|
|
124
|
+
files: Dictionary<IVectorFile>;
|
|
119
125
|
}
|
|
120
126
|
export interface IVectorSearchContent {
|
|
121
127
|
type: 'text';
|
|
122
128
|
text: string;
|
|
123
129
|
}
|
|
124
130
|
export interface IVectorSearchResult {
|
|
125
|
-
attributes: Dictionary<
|
|
131
|
+
attributes: Dictionary<ItemType> | null;
|
|
126
132
|
content: IVectorSearchContent[];
|
|
127
133
|
file_id: string;
|
|
128
134
|
filename: string;
|
|
@@ -130,14 +136,17 @@ export interface IVectorSearchResult {
|
|
|
130
136
|
}
|
|
131
137
|
export interface IOpenAIServiceWithVectorStore extends IOpenAIServiceWithTools {
|
|
132
138
|
vectorStore?: Dictionary<IVectorStore>;
|
|
139
|
+
vsMetadata: IDataItem[];
|
|
140
|
+
fileAttributes: IDataItem[];
|
|
133
141
|
initializeVectorStore(): Promise<boolean>;
|
|
134
142
|
getVectorStore(vectorStoreId: string): IVectorStore | undefined;
|
|
135
|
-
addVectorStore(vectorStoreName: string): Promise<boolean>;
|
|
136
|
-
addFile(fileUrl: string | File, vectorStoreName: string, wait?: boolean): Promise<boolean>;
|
|
143
|
+
addVectorStore(vectorStoreName: string, metadata?: Dictionary<string>): Promise<boolean>;
|
|
144
|
+
addFile(fileUrl: string | File, vectorStoreName: string, attributes?: Dictionary<ItemType>, wait?: boolean): Promise<boolean>;
|
|
145
|
+
setAttributes(vectorStoreName: string, fileId: string | null, attributes: Dictionary<ItemType>): Promise<boolean>;
|
|
137
146
|
deleteFile(fileId: string): Promise<boolean>;
|
|
138
|
-
deleteVectorStore(
|
|
147
|
+
deleteVectorStore(vectorStoreName: string): Promise<boolean>;
|
|
139
148
|
searchVectoreStore(vectorStoreName: string, query: string | string[], rewriteQuery?: boolean, maxNumResults?: number, filters?: ICompoundFilter | IComparisonFilter): Promise<IVectorSearchResult[]>;
|
|
140
|
-
|
|
149
|
+
getFile(fileUrl: string): IVectorFile | undefined;
|
|
141
150
|
}
|
|
142
151
|
export interface IOpenAIAppConfig {
|
|
143
152
|
officeAITools: string;
|
package/dist/types.d.ts
CHANGED
|
@@ -104,12 +104,14 @@ export interface IAppState extends IAppInfo {
|
|
|
104
104
|
toggleFullScreen(): Promise<boolean>;
|
|
105
105
|
}
|
|
106
106
|
export type ItemType = string | number | boolean;
|
|
107
|
-
export interface
|
|
107
|
+
export interface IDataItem {
|
|
108
108
|
name: string;
|
|
109
|
-
description: string;
|
|
110
109
|
values?: string[];
|
|
111
110
|
value: ItemType;
|
|
112
111
|
default: ItemType;
|
|
112
|
+
}
|
|
113
|
+
export interface IConfigItem extends IDataItem {
|
|
114
|
+
description: string;
|
|
113
115
|
doNotChange: boolean;
|
|
114
116
|
scopes: EScope;
|
|
115
117
|
}
|
package/package.json
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { inject, ref, reactive } from 'vue';
|
|
3
3
|
import { appConfigSymbol, AppConfig, Dictionary } from '@christianriedl/utils';
|
|
4
4
|
import { getOpenAISymbol, IOpenAIServiceWithVectorStore, IOpenAIAppConfig, IOpenAIOptions, ITool, IMcpTool, IFileSearchTool } from '@christianriedl/utils';
|
|
5
|
+
import OpenAIMetaData from '@christianriedl/utils/src/components/OpenAIMetaData.vue';
|
|
5
6
|
|
|
6
7
|
interface IFunction {
|
|
7
8
|
name: string;
|
|
@@ -30,6 +31,9 @@
|
|
|
30
31
|
const selectedVectorStoreName = ref('');
|
|
31
32
|
const selectedVectorStoreFile = ref('');
|
|
32
33
|
const showFunctions = ref(false);
|
|
34
|
+
const showMetaData = ref(false);
|
|
35
|
+
const editVectorStore = ref(false);
|
|
36
|
+
const metadata = ref<Dictionary<ItemType>>({});
|
|
33
37
|
const toolName = ref('');
|
|
34
38
|
const toolFunctions = reactive<IFunction[]>([]);
|
|
35
39
|
let fileHandle: FileSystemFileHandle | null = null;
|
|
@@ -172,8 +176,16 @@
|
|
|
172
176
|
}
|
|
173
177
|
initializeTools();
|
|
174
178
|
}
|
|
179
|
+
async function editVectorStore() {
|
|
180
|
+
const vs = openAI.vectorStore![selectedVectorStoreName.value];
|
|
181
|
+
if (vs) {
|
|
182
|
+
editVectorStore.value = true;
|
|
183
|
+
metadata.value = vs.metadata ? vs.metadata : openAI.vsMetadata;
|
|
184
|
+
showMetaData.value = true;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
175
187
|
async function addFile() {
|
|
176
|
-
if (openAI.
|
|
188
|
+
if (openAI.getFile(selectedVectorStoreFile.value)) {
|
|
177
189
|
alert('File already exists, add a new file path or url !');
|
|
178
190
|
return;
|
|
179
191
|
}
|
|
@@ -189,30 +201,42 @@
|
|
|
189
201
|
}
|
|
190
202
|
}
|
|
191
203
|
async function deleteFile() {
|
|
192
|
-
const
|
|
193
|
-
if (!
|
|
204
|
+
const file = openAI.getFile(selectedVectorStoreFile.value);
|
|
205
|
+
if (!file) {
|
|
194
206
|
alert('File not existing !');
|
|
195
207
|
return;
|
|
196
208
|
}
|
|
197
|
-
if (!await openAI.deleteFile(
|
|
209
|
+
if (!await openAI.deleteFile(file.id)) {
|
|
198
210
|
alert('File not deleted, error ! ');
|
|
199
211
|
}
|
|
200
212
|
else {
|
|
201
213
|
vectorStoreSelected();
|
|
202
214
|
}
|
|
203
215
|
}
|
|
204
|
-
async function
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
selectedVectorStoreFile.value = fileHandle.name;
|
|
211
|
-
}
|
|
216
|
+
async function editFile() {
|
|
217
|
+
const file = openAI.getFile(selectedVectorStoreFile.value);
|
|
218
|
+
if (file) {
|
|
219
|
+
editVectorStore.value = false;
|
|
220
|
+
metadata.value = file.attributes ? file.attributes : openAI.fileAttributes;
|
|
221
|
+
showMetaData.value = true;
|
|
212
222
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
223
|
+
}
|
|
224
|
+
async function saveMetaData(items?: Dictionary<ItemType>) {
|
|
225
|
+
showMetaData.value = false;
|
|
226
|
+
if (items) {
|
|
227
|
+
if (editVectorStore.value) {
|
|
228
|
+
if (await openAI.setAttributes(selectedVectorStoreName.value, null, items as Dictionary<string>)) {
|
|
229
|
+
vs.metadata = items;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
const file = openAI.getFile(selectedVectorStoreFile.value);
|
|
234
|
+
if (file) {
|
|
235
|
+
if (await openAI.setAttributes(selectedVectorStoreName.value, file.id, items)) {
|
|
236
|
+
file.attributes = items;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
216
240
|
}
|
|
217
241
|
}
|
|
218
242
|
</script>
|
|
@@ -222,7 +246,7 @@
|
|
|
222
246
|
<h4>OpenAI Settings</h4>
|
|
223
247
|
<v-row dense align="center">
|
|
224
248
|
<v-col cols="3">
|
|
225
|
-
<v-select v-model="options.model" :items="openAI.modelNames" hide-details density="compact"
|
|
249
|
+
<v-select v-model="options.model" :items="openAI.modelNames" hide-details density="compact"
|
|
226
250
|
label="Model" @update:modelValue="onOptionChange">
|
|
227
251
|
</v-select>
|
|
228
252
|
</v-col>
|
|
@@ -312,27 +336,32 @@
|
|
|
312
336
|
</template>
|
|
313
337
|
<v-row dense align="center">
|
|
314
338
|
<v-col cols="2">
|
|
315
|
-
<v-btn class="bg-office" @click="emits('back')">
|
|
339
|
+
<v-btn class="bg-office" @click="emits('back')">
|
|
340
|
+
BACK
|
|
316
341
|
<v-icon icon="$back"></v-icon>
|
|
317
342
|
</v-btn>
|
|
318
343
|
</v-col>
|
|
319
344
|
<v-col cols="2">
|
|
320
|
-
<v-btn :disabled="!optionsChanged && !toolsChanged" class="bg-office" @click="onSave">
|
|
345
|
+
<v-btn :disabled="!optionsChanged && !toolsChanged" class="bg-office" @click="onSave">
|
|
346
|
+
SAVE
|
|
321
347
|
<v-icon icon="$save"></v-icon>
|
|
322
348
|
</v-btn>
|
|
323
349
|
</v-col>
|
|
324
350
|
<v-col cols="2">
|
|
325
|
-
<v-btn :disabled="!useChanged" class="bg-office" @click="onSaveUsage">
|
|
351
|
+
<v-btn :disabled="!useChanged" class="bg-office" @click="onSaveUsage">
|
|
352
|
+
SAVE TOOL USE
|
|
326
353
|
<v-icon icon="$save"></v-icon>
|
|
327
354
|
</v-btn>
|
|
328
355
|
</v-col>
|
|
329
356
|
<v-col cols="2">
|
|
330
|
-
<v-btn class="bg-office" @click="onAddMcp">
|
|
357
|
+
<v-btn class="bg-office" @click="onAddMcp">
|
|
358
|
+
ADD MCP
|
|
331
359
|
<v-icon icon="$plus"></v-icon>
|
|
332
360
|
</v-btn>
|
|
333
361
|
</v-col>
|
|
334
362
|
<v-col cols="2">
|
|
335
|
-
<v-btn class="bg-office" @click="onAddSearch">
|
|
363
|
+
<v-btn class="bg-office" @click="onAddSearch">
|
|
364
|
+
ADD SEARCH
|
|
336
365
|
<v-icon icon="$plus"></v-icon>
|
|
337
366
|
</v-btn>
|
|
338
367
|
</v-col>
|
|
@@ -345,11 +374,10 @@
|
|
|
345
374
|
<v-col cols="2">
|
|
346
375
|
<v-combobox v-model="selectedVectorStoreName" :items="vectorStoreNames" hide-details density="compact" @update:modelValue="vectorStoreSelected()"></v-combobox>
|
|
347
376
|
</v-col>
|
|
348
|
-
<v-col cols="
|
|
349
|
-
<v-btn variant="text" prepend-icon="$delete" @click="deleteVectorStore">VS</v-btn>
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
<v-btn variant="text" prepend-icon="$plus" @click="addVectorStore">VS</v-btn>
|
|
377
|
+
<v-col cols="2">
|
|
378
|
+
<v-btn disabled="!selectedVectorStoreName" variant="text" prepend-icon="$delete" @click="deleteVectorStore">VS</v-btn>
|
|
379
|
+
<v-btn disabled="!selectedVectorStoreName" variant="text" prepend-icon="$plus" @click="addVectorStore">VS</v-btn>
|
|
380
|
+
<v-btn disabled="!selectedVectorStoreName" variant="text" prepend-icon="$pencil" @click="editVectorStore">VS</v-btn>
|
|
353
381
|
</v-col>
|
|
354
382
|
<v-col cols="5">
|
|
355
383
|
<v-combobox v-model="selectedVectorStoreFile" :items="vectorStoreFiles" hide-details density="compact"></v-combobox>
|
|
@@ -358,13 +386,15 @@
|
|
|
358
386
|
<v-btn variant="text" prepend-icon="$search" @click="searchFile">FILE</v-btn>
|
|
359
387
|
</v-col>
|
|
360
388
|
<v-col cols="1">
|
|
361
|
-
<v-btn variant="text" prepend-icon="$delete" @click="deleteFile">FILE</v-btn>
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
<v-btn variant="text" prepend-icon="$plus" @click="addFile">FILE</v-btn>
|
|
389
|
+
<v-btn disabled="!selectedVectorStoreFile" variant="text" prepend-icon="$delete" @click="deleteFile">FILE</v-btn>
|
|
390
|
+
<v-btn disabled="!selectedVectorStoreFile" variant="text" prepend-icon="$plus" @click="addFile">FILE</v-btn>
|
|
391
|
+
<v-btn disabled="!selectedVectorStoreFile" variant="text" prepend-icon="$pencil" @click="editFile">VS</v-btn>
|
|
365
392
|
</v-col>
|
|
366
393
|
</v-row>
|
|
367
394
|
</template>
|
|
395
|
+
<v-dialog v-model="showMetaData">
|
|
396
|
+
<OpenAIMetaData :items="metadata" :vectorstore="editVectorStore" @back="saveMetaData"></OpenAIMetaData>
|
|
397
|
+
</v-dialog>
|
|
368
398
|
<v-dialog v-model="showFunctions">
|
|
369
399
|
<v-container fluid class="bg-office overflow-y-auto">
|
|
370
400
|
<h4>{{toolName + " functions"}}</h4>
|
|
@@ -374,7 +404,8 @@
|
|
|
374
404
|
</v-row>
|
|
375
405
|
<v-row dense align="center">
|
|
376
406
|
<v-col cols="2">
|
|
377
|
-
<v-btn class="bg-office" @click="showFunctions = false">
|
|
407
|
+
<v-btn class="bg-office" @click="showFunctions = false">
|
|
408
|
+
BACK
|
|
378
409
|
<v-icon icon="$back"></v-icon>
|
|
379
410
|
</v-btn>
|
|
380
411
|
</v-col>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { inject, computed, ref, StyleValue } from 'vue';
|
|
3
|
+
import { IDataItem, Dictionary } from '@christianriedl/utils'
|
|
4
|
+
import SettingsLine from '../components/SettingsLine.vue';
|
|
5
|
+
|
|
6
|
+
const props = defineProps<{ items: IDataItem[], vectorstore: boolean }>();
|
|
7
|
+
const emits = defineEmits<{ (e: 'back', items?: IDataItem[]): void }>();
|
|
8
|
+
const items: IDataItem[] = [];
|
|
9
|
+
for (const it of props.items) {
|
|
10
|
+
items.push(Object.assign({}, it);
|
|
11
|
+
}
|
|
12
|
+
const header = props.vectorstore ? "Vector Store Metadata" : "File Attributes";
|
|
13
|
+
const changedItems = new Set<string>();
|
|
14
|
+
const changed = ref(false);
|
|
15
|
+
|
|
16
|
+
function onChange(item: IDataItem, changed: boolean) {
|
|
17
|
+
if (changed)
|
|
18
|
+
changedItems.add(item.name);
|
|
19
|
+
else
|
|
20
|
+
changedItems.delete(item.name);
|
|
21
|
+
changed.value = changedItems.size > 0;
|
|
22
|
+
}
|
|
23
|
+
function onBack(save: boolean) {
|
|
24
|
+
if (save) {
|
|
25
|
+
emits('back', items);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
emits('back');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<template>
|
|
34
|
+
<v-container fluid >
|
|
35
|
+
<h4>{{header}}</h4>
|
|
36
|
+
<v-table>
|
|
37
|
+
<thead>
|
|
38
|
+
<tr>
|
|
39
|
+
<th style="width:50%">Name</th>
|
|
40
|
+
<th style="width:50%">Value</th>
|
|
41
|
+
</tr>
|
|
42
|
+
</thead>
|
|
43
|
+
<tbody>
|
|
44
|
+
<settings-line v-for="item in items" :key="item.name" :item="item" @change="onChange(item, true)" @clear="onChange(item, false)"></settings-line>
|
|
45
|
+
<tr>
|
|
46
|
+
<td style="width:50%">
|
|
47
|
+
<v-btn @click="onBack(false)">BACK</v-btn>
|
|
48
|
+
<v-btn v-if="changed" @click="onBack(true)">SAVE</v-btn>
|
|
49
|
+
</td>
|
|
50
|
+
<td style="width:50%"></td>
|
|
51
|
+
</tr>
|
|
52
|
+
</tbody>
|
|
53
|
+
</v-table>
|
|
54
|
+
</v-container>
|
|
55
|
+
</template>
|
|
@@ -1,36 +1,41 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { reactive } from 'vue';
|
|
3
|
-
import { IConfigItem, ItemType, EScope } from '@christianriedl/utils';
|
|
3
|
+
import { IConfigItem, IDataItem, ItemType, EScope } from '@christianriedl/utils';
|
|
4
4
|
|
|
5
|
-
const props = defineProps<{item: IConfigItem; scopes
|
|
6
|
-
const emits = defineEmits<{ (e: 'change',
|
|
5
|
+
const props = defineProps<{ item: IConfigItem | IDataItem; scopes?: EScope, clearable?: boolean }>();
|
|
6
|
+
const emits = defineEmits<{ (e: 'change'): void, (e: 'clear'): void }>();
|
|
7
7
|
|
|
8
8
|
const item = reactive(props.item);
|
|
9
9
|
const isString = typeof item.default === 'string' && !item.values;
|
|
10
10
|
const isEnum = typeof item.default === 'string' && item.values;
|
|
11
11
|
const isNumber = typeof item.default === 'number';
|
|
12
12
|
const isBoolean = typeof item.default === 'boolean';
|
|
13
|
-
const isDisabled = item.doNotChange;
|
|
14
|
-
const isVisible = (item.scopes & props.scopes) != 0;
|
|
13
|
+
const isDisabled = (item as IConfigItem).doNotChange;
|
|
14
|
+
const isVisible = !props.scopes || ((item as IConfigItem).scopes & props.scopes) != 0;
|
|
15
15
|
const enumValues: ItemType[] = item.values!;
|
|
16
|
+
const description = (item as IConfigItem).description || item.name;
|
|
16
17
|
|
|
17
18
|
function onChange() {
|
|
18
|
-
|
|
19
|
+
emits('change');
|
|
20
|
+
}
|
|
21
|
+
function onClear() {
|
|
22
|
+
item.value = item.default;
|
|
23
|
+
emits('clear');
|
|
19
24
|
}
|
|
20
25
|
</script>
|
|
21
26
|
|
|
22
27
|
<template>
|
|
23
28
|
<tr v-if="isVisible" class="settingsline">
|
|
24
|
-
<td style="width:50%">{{
|
|
29
|
+
<td style="width:50%">{{description}}</td>
|
|
25
30
|
<td style="width:50%">
|
|
26
|
-
<v-switch v-if="isBoolean" v-model="item.value" :disabled="isDisabled" density="compact" hide-details
|
|
27
|
-
|
|
28
|
-
<v-text-field v-if="
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
<v-switch v-if="isBoolean" v-model="item.value" :disabled="isDisabled" density="compact" hide-details color="primary"
|
|
32
|
+
:append-icon="props.clearable ? '$clear' : undefined" @update:modelValue="onChange" @click:append="onClear"></v-switch>
|
|
33
|
+
<v-text-field v-if="isString" v-model="item.value" :disabled="isDisabled" :clearable="props.clearable" density="compact"
|
|
34
|
+
hide-details type="string" @update:modelValue="onChange" @click:clear="onClear"></v-text-field>
|
|
35
|
+
<v-text-field v-if="isNumber" v-model="item.value" :disabled="isDisabled" :clearable="props.clearable" density="compact"
|
|
36
|
+
hide-details type="number" @update:modelValue="onChange" @click:clear="onClear"></v-text-field>
|
|
37
|
+
<v-select v-if="isEnum" name="enum" density="compact" v-model="item.value" :disabled="isDisabled" :clearable="props.clearable"
|
|
38
|
+
:items="enumValues" persistent-hint @update:modelValue="onChange" @click:clear="onClear" dense solo hide-details single-line>
|
|
34
39
|
</v-select>
|
|
35
40
|
</td>
|
|
36
41
|
</tr>
|