@christianriedl/utils 1.0.135 → 1.0.137
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/package.json +1 -1
- package/src/components/OpenAI.vue +14 -13
- package/src/components/OpenAIConfig.vue +44 -9
package/package.json
CHANGED
|
@@ -24,9 +24,10 @@
|
|
|
24
24
|
const isUpload = ref(false);
|
|
25
25
|
const showConfig = ref(false);
|
|
26
26
|
const files = ref<File[]>([]);
|
|
27
|
-
const
|
|
27
|
+
const imageUrl = ref("");
|
|
28
28
|
const camera = ref<InstanceType<typeof Camera>>();
|
|
29
29
|
const htmlText = ref('');
|
|
30
|
+
const tools = ref(props.tools);
|
|
30
31
|
|
|
31
32
|
onUnmounted(() => {
|
|
32
33
|
openAI.clearContext();
|
|
@@ -40,18 +41,18 @@
|
|
|
40
41
|
isUpload.value = false;
|
|
41
42
|
let answer: IResponseResult;
|
|
42
43
|
if (camera.value) {
|
|
43
|
-
|
|
44
|
+
imageUrl.value = await camera.value.snapshot() as string;
|
|
44
45
|
camera.value.stop();
|
|
45
46
|
camera.value = undefined;
|
|
46
47
|
isCamera.value = false;
|
|
47
48
|
}
|
|
48
|
-
if (
|
|
49
|
-
answer = await openAI.response(question.value, undefined,
|
|
50
|
-
|
|
49
|
+
if (imageUrl.value) {
|
|
50
|
+
answer = await openAI.response(question.value, undefined, imageUrl.value);
|
|
51
|
+
imageUrl.value = "";
|
|
51
52
|
}
|
|
52
53
|
else {
|
|
53
|
-
if (
|
|
54
|
-
answer = await openAI.response(question.value,
|
|
54
|
+
if (tools.value !== undefined) {
|
|
55
|
+
answer = await openAI.response(question.value, tools.value);
|
|
55
56
|
}
|
|
56
57
|
else {
|
|
57
58
|
answer = await openAI.response(question.value);
|
|
@@ -67,7 +68,6 @@
|
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
if (openAI.options.outputFormat == 'html') {
|
|
70
|
-
|
|
71
71
|
const tempDiv = document.createElement('div');
|
|
72
72
|
if (answer.text.startsWith('```html\n')) {
|
|
73
73
|
if (answer.text.endsWith('\n```')) {
|
|
@@ -121,13 +121,14 @@
|
|
|
121
121
|
const reader = new FileReader();
|
|
122
122
|
reader.addEventListener("load", async () => {
|
|
123
123
|
// convert image file to base64 string
|
|
124
|
-
|
|
124
|
+
imageUrl.value = reader.result as string;
|
|
125
125
|
}, false,);
|
|
126
126
|
reader.readAsDataURL(files.value[0]);
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
|
-
function onUse(
|
|
130
|
-
|
|
129
|
+
function onUse(usetools: string[], persist: boolean) {
|
|
130
|
+
tools.value = usetools;
|
|
131
|
+
emits('use', usetools, persist);
|
|
131
132
|
}
|
|
132
133
|
// Move to some library
|
|
133
134
|
async function markdownToHtml(markdownText: string): Promise<string> {
|
|
@@ -189,7 +190,7 @@
|
|
|
189
190
|
</v-file-input>
|
|
190
191
|
</v-col>
|
|
191
192
|
<v-col cols="6">
|
|
192
|
-
<img width="100%" :src="
|
|
193
|
+
<img width="100%" :src="imageUrl">
|
|
193
194
|
</v-col>
|
|
194
195
|
</v-row>
|
|
195
196
|
<v-row v-if="htmlText" dense >
|
|
@@ -201,7 +202,7 @@
|
|
|
201
202
|
<v-col cols="12">{{line}}</v-col>
|
|
202
203
|
</v-row>
|
|
203
204
|
<v-dialog v-model="showConfig" :fullscreen="isMobile">
|
|
204
|
-
<OpenAIConfig :tools="
|
|
205
|
+
<OpenAIConfig :tools="tools" :ismobile="isMobile" @use="onUse" @back="showConfig=false"></OpenAIConfig>
|
|
205
206
|
</v-dialog>
|
|
206
207
|
</v-container>
|
|
207
208
|
</template>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { inject, ref, reactive } from 'vue';
|
|
3
3
|
import { appConfigSymbol, AppConfig, Dictionary } from '@christianriedl/utils';
|
|
4
|
-
import { getOpenAISymbol, IOpenAIServiceWithVectorStore, IOpenAIAppConfig, IOpenAIOptions, ITool } from '@christianriedl/utils';
|
|
4
|
+
import { getOpenAISymbol, IOpenAIServiceWithVectorStore, IOpenAIAppConfig, IOpenAIOptions, ITool, IMcpTool, IFileSearchTool } from '@christianriedl/utils';
|
|
5
5
|
|
|
6
6
|
interface IFunction {
|
|
7
7
|
name: string;
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
const selectedVectorStoreName = ref('');
|
|
31
31
|
const selectedVectorStoreFile = ref('');
|
|
32
32
|
const showFunctions = ref(false);
|
|
33
|
-
const toolName = ref
|
|
34
|
-
const
|
|
33
|
+
const toolName = ref('');
|
|
34
|
+
const toolFunctions = reactive<IFunction[]>([]);
|
|
35
35
|
let fileHandle: FileSystemFileHandle | null = null;
|
|
36
36
|
|
|
37
37
|
initializeTools();
|
|
@@ -78,7 +78,8 @@
|
|
|
78
78
|
toolName.value = serverLabel;
|
|
79
79
|
const res = await openAI.getToolFunctions(serverLabel);
|
|
80
80
|
if (res.json) {
|
|
81
|
-
|
|
81
|
+
const funcs = res.json.tools as IFunction[];
|
|
82
|
+
toolFunctions.splice(0, toolFunctions.length, ...funcs);
|
|
82
83
|
showFunctions.value = true;
|
|
83
84
|
}
|
|
84
85
|
}
|
|
@@ -87,6 +88,7 @@
|
|
|
87
88
|
if (toolsChanged.value) {
|
|
88
89
|
for (const key in fileSearch) {
|
|
89
90
|
const vsNames = fileSearch[key];
|
|
91
|
+
tools[key].vector_store_ids.splice(0, tools[key].vector_store_ids.length);
|
|
90
92
|
for (let i = 0; i < vsNames.length; i++) {
|
|
91
93
|
tools[key].vector_store_ids[i] = openAI.vectorStore![vsNames[i]].id;
|
|
92
94
|
}
|
|
@@ -118,6 +120,29 @@
|
|
|
118
120
|
emits('use', useTools, persist);
|
|
119
121
|
useChanged.value = false;
|
|
120
122
|
}
|
|
123
|
+
function onAddMcp() {
|
|
124
|
+
const name = window.prompt('Enter MCP name:');
|
|
125
|
+
if (name && name.length > 0) {
|
|
126
|
+
if (tools[name]) {
|
|
127
|
+
alert('Tool with this name already exists, please choose another name !');
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const mcpTool: IMcpTool = { type: 'mcp', server_label: name, server_url: '<set url>', require_approval: 'never' };
|
|
131
|
+
tools[name] = mcpTool;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function onAddSearch() {
|
|
135
|
+
const name = window.prompt('Enter File search name:');
|
|
136
|
+
if (name && name.length > 0) {
|
|
137
|
+
if (tools[name]) {
|
|
138
|
+
alert('Tool with this name already exists, please choose another name !');
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const searchTool: IFileSearchTool = { type: 'file_search', vector_store_ids: [] };
|
|
142
|
+
tools[name] = searchTool;
|
|
143
|
+
fileSearch[name] = [];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
121
146
|
function vectorStoreSelected() {
|
|
122
147
|
selectedVectorStoreFile.value = '';
|
|
123
148
|
const vs = openAI.vectorStore![selectedVectorStoreName.value];
|
|
@@ -245,8 +270,8 @@
|
|
|
245
270
|
density="compact" label="Approval" @update:modelValue="onToolChange">
|
|
246
271
|
</v-select>
|
|
247
272
|
</v-col>
|
|
248
|
-
<v-col v-if="!props.
|
|
249
|
-
<v-btn variant="text" prepend-icon="$search"
|
|
273
|
+
<v-col v-if="!props.ismobile" cols="1">
|
|
274
|
+
<v-btn variant="text" prepend-icon="$search" @click="showTools(tool.server_label)">TOOLS</v-btn>
|
|
250
275
|
</v-col>
|
|
251
276
|
<v-col cols="1">
|
|
252
277
|
<v-checkbox v-model="use[key]" label="Use" hide-details density="compact" @update:modelValue="onUseChange"></v-checkbox>
|
|
@@ -301,6 +326,16 @@
|
|
|
301
326
|
<v-icon icon="$save"></v-icon>
|
|
302
327
|
</v-btn>
|
|
303
328
|
</v-col>
|
|
329
|
+
<v-col cols="2">
|
|
330
|
+
<v-btn class="bg-office" @click="onAddMcp">ADD MCP
|
|
331
|
+
<v-icon icon="$plus"></v-icon>
|
|
332
|
+
</v-btn>
|
|
333
|
+
</v-col>
|
|
334
|
+
<v-col cols="2">
|
|
335
|
+
<v-btn class="bg-office" @click="onAddSearch">ADD SEARCH
|
|
336
|
+
<v-icon icon="$plus"></v-icon>
|
|
337
|
+
</v-btn>
|
|
338
|
+
</v-col>
|
|
304
339
|
</v-row>
|
|
305
340
|
<template v-if="!props.ismobile && openAI.vectorStore">
|
|
306
341
|
<v-divider></v-divider>
|
|
@@ -333,9 +368,9 @@
|
|
|
333
368
|
<v-dialog v-model="showFunctions">
|
|
334
369
|
<v-container fluid class="bg-office overflow-y-auto">
|
|
335
370
|
<h4>{{toolName + " functions"}}</h4>
|
|
336
|
-
<v-row dense align="center" v-for="func in
|
|
337
|
-
<v-col cols="
|
|
338
|
-
<v-col cols="
|
|
371
|
+
<v-row dense align="center" v-for="func in toolFunctions" :key="func.name">
|
|
372
|
+
<v-col cols="4">{{func.name}}</v-col>
|
|
373
|
+
<v-col cols="8">{{func.description}}</v-col>
|
|
339
374
|
</v-row>
|
|
340
375
|
<v-row dense align="center">
|
|
341
376
|
<v-col cols="2">
|