@christianriedl/utils 1.0.152 → 1.0.154

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 CHANGED
@@ -44,7 +44,7 @@ export interface ISchema {
44
44
  schema?: Dictionary<unknown>;
45
45
  }
46
46
  export interface ITool {
47
- type: 'mcp' | 'file_search' | 'web_search_preview' | 'web_search_preview_2025_03_11' | 'function' | 'image_generation';
47
+ type: 'mcp' | 'file_search' | 'web_search' | 'function' | 'image_generation';
48
48
  }
49
49
  export interface IMcpTool extends ITool {
50
50
  type: 'mcp';
@@ -77,7 +77,8 @@ export interface IImageGenerationTool extends ITool {
77
77
  size?: '1024x1024' | '1024x1536' | '1536x1024' | 'auto';
78
78
  }
79
79
  export interface IWebSearchTool extends ITool {
80
- type: 'web_search_preview' | 'web_search_preview_2025_03_11';
80
+ type: 'web_search';
81
+ allowed_domains?: string;
81
82
  search_context_size?: 'low' | 'medium' | 'high';
82
83
  user_location?: IWebSearchLocation | null;
83
84
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@christianriedl/utils",
3
- "version": "1.0.152",
3
+ "version": "1.0.154",
4
4
  "description": "Interfaces, local storage, service worker, configuration, application state",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -25,7 +25,6 @@
25
25
  const isUpload = ref(false);
26
26
  const showConfig = ref(false);
27
27
  const showFilter = ref(false);
28
- const files = ref<File[]>([]);
29
28
  const imageUrl = ref("");
30
29
  const camera = ref<InstanceType<typeof Camera>>();
31
30
  const htmlText = ref('');
@@ -42,7 +41,6 @@
42
41
 
43
42
  async function onComplete() {
44
43
  htmlText.value = "<h4>WAITING ...</h4>";
45
- files.value = [];
46
44
  isUpload.value = false;
47
45
  let answer: IResponseResult;
48
46
  if (camera.value) {
@@ -124,17 +122,35 @@
124
122
  camera.value = undefined;
125
123
  }
126
124
  }
127
- function onFile() {
125
+ async function fileUpload() {
126
+ replyLines.value = [];
127
+ htmlText.value = '';
128
+ isCamera.value = false;
129
+ if (camera.value) {
130
+ camera.value.stop();
131
+ camera.value = undefined;
132
+ }
128
133
  if (!question.value) {
129
134
  question.value = "Was erkennst du auf dem Bild ?";
130
135
  }
131
- if (files.value && files.value.length > 0) {
136
+ const pickerOpts = {
137
+ types: [{
138
+ description: "Images",
139
+ accept: { "image/*": [".png", ".gif", ".jpeg", ".jpg"] }
140
+ }],
141
+ excludeAcceptAllOption: true,
142
+ multiple: false,
143
+ };
144
+ const files: FileSystemFileHandle[] = await(window as any).showOpenFilePicker(pickerOpts);
145
+ if (files && files.length > 0) {
146
+ const file = await files[0].getFile();
132
147
  const reader = new FileReader();
133
148
  reader.addEventListener("load", async () => {
134
149
  // convert image file to base64 string
135
150
  imageUrl.value = reader.result as string;
151
+ isUpload.value = true;
136
152
  }, false,);
137
- reader.readAsDataURL(files.value[0]);
153
+ reader.readAsDataURL(file);
138
154
  }
139
155
  }
140
156
  function onUse(usetools: string[], persist: boolean) {
@@ -189,7 +205,7 @@
189
205
  <v-btn variant="tonal" class="bg-office aibutton" @click="onCamera">
190
206
  <v-icon size="large" icon="$webcam" color="primary"></v-icon>
191
207
  </v-btn>
192
- <v-btn variant="tonal" class="bg-office aibutton" @click="isUpload=true;replyLines=[]">
208
+ <v-btn variant="tonal" class="bg-office aibutton" @click="fileUpload">
193
209
  <v-icon size="large" icon="$image" color="primary"></v-icon>
194
210
  </v-btn>
195
211
  </v-col>
@@ -205,12 +221,8 @@
205
221
  </v-col>
206
222
  </v-row>
207
223
  <v-row v-if="isUpload" dense align="center">
208
- <v-col cols="6">
209
- <v-file-input show-size clearable multiple hide-details v-model="files" accept="image/*" label="Select File" prepend-icon="" append-icon="" @update:modelValue="onFile">
210
- </v-file-input>
211
- </v-col>
212
- <v-col cols="6">
213
- <img width="100%" :src="imageUrl">
224
+ <v-col cols="12">
225
+ <v-img :src="imageUrl"></v-img>
214
226
  </v-col>
215
227
  </v-row>
216
228
  <v-row v-if="htmlText" dense>
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { inject, ref, reactive } from 'vue';
2
+ import { inject, ref, reactive, onBeforeUnmount } from 'vue';
3
3
  import { appConfigSymbol, AppConfig, Dictionary, IDataItem, ItemType, IVectorFile } from '@christianriedl/utils';
4
4
  import { getOpenAISymbol, IOpenAIServiceWithVectorStore, IOpenAIAppConfig, IOpenAIOptions, ITool, IMcpTool, IFileSearchTool } from '@christianriedl/utils';
5
5
  import OpenAIMetaData from '@christianriedl/utils/src/components/OpenAIMetaData.vue';
@@ -40,6 +40,8 @@
40
40
  let fileHandle: FileSystemFileHandle | null = null;
41
41
  let vsSelected = false;
42
42
 
43
+ onBeforeUnmount(() => onBack());
44
+
43
45
  initializeTools();
44
46
  checkAllFilter();
45
47
 
@@ -67,7 +69,7 @@
67
69
  }
68
70
  fileSearch[key] = names;
69
71
  }
70
- else if (tool.type.startsWith("web_search")) {
72
+ else if (tool.type === "web_search") {
71
73
  tool.user_location = Object.assign({}, tool.user_location);
72
74
  }
73
75
  }
@@ -99,8 +101,11 @@
99
101
  showFunctions.value = true;
100
102
  }
101
103
  }
102
- function onSave() {
103
- const persist = window.confirm('Do you want to persist the changes?');
104
+ function onSave(ask: boolean) {
105
+ let persist = false;
106
+ if (ask) {
107
+ persist = window.confirm('Do you want to persist the changes?');
108
+ }
104
109
  if (toolsChanged.value) {
105
110
  for (const key in fileSearch) {
106
111
  const vsNames = fileSearch[key];
@@ -125,8 +130,11 @@
125
130
  optionsChanged.value = false;
126
131
  }
127
132
  }
128
- function onSaveUsage() {
129
- const persist = window.confirm('Do you want to persist the changes?');
133
+ function onSaveUsage(ask: boolean) {
134
+ let persist = false;
135
+ if (ask) {
136
+ persist = window.confirm('Do you want to persist the changes?');
137
+ }
130
138
  const useTools: string[] = [];
131
139
  for (const key in use) {
132
140
  if (use[key]) {
@@ -136,6 +144,13 @@
136
144
  emits('use', useTools, persist);
137
145
  useChanged.value = false;
138
146
  }
147
+ function onBack() {
148
+ if (optionsChanged.value)
149
+ onSave(false);
150
+ if (useChanged.value)
151
+ onSaveUsage(false);
152
+ emits("back");
153
+ }
139
154
  function onAddMcp() {
140
155
  const name = window.prompt('Enter MCP name:');
141
156
  if (name && name.length > 0) {
@@ -458,19 +473,22 @@
458
473
  <v-checkbox v-model="use[key]" label="Use" hide-details density="compact" @update:modelValue="onUseChange"></v-checkbox>
459
474
  </v-col>
460
475
  </v-row>
461
- <v-row v-if="tool.type.startsWith('web_search')" dense align="center">
476
+ <v-row v-if="tool.type == 'web_search'" dense align="center">
462
477
  <v-col cols="1">
463
- <v-text-field :model-value="key" type="string" hide-details disabled label="file_search" density="compact" @change="onToolChange"></v-text-field>
478
+ <v-text-field :model-value="key" type="string" hide-details disabled label="web_search" density="compact" @change="onToolChange"></v-text-field>
464
479
  </v-col>
465
480
  <v-col cols="2">
466
481
  <v-text-field v-model="tool.user_location.country" type="string" hide-details :clearable="canClear" label="Country" density="compact" @change="onToolChange"></v-text-field>
467
482
  </v-col>
468
- <v-col cols="3">
483
+ <v-col cols="2">
469
484
  <v-text-field v-model="tool.user_location.city" type="string" hide-details :clearable="canClear" label="City" density="compact" @change="onToolChange"></v-text-field>
470
485
  </v-col>
471
- <v-col cols="4">
486
+ <v-col cols="2">
472
487
  <v-text-field v-model="tool.user_location.region" type="string" hide-details :clearable="canClear" label="Region" density="compact" @change="onToolChange"></v-text-field>
473
488
  </v-col>
489
+ <v-col cols="3">
490
+ <v-text-field v-model="tool.allowed_domains" type="string" hide-details :clearable="canClear" label="Allowed domains" density="compact" @change="onToolChange"></v-text-field>
491
+ </v-col>
474
492
  <v-col cols="1">
475
493
  <v-btn icon="$delete" variant="tonal" @click.stop.prevent="onDelete(key)"></v-btn>
476
494
  </v-col>
@@ -507,19 +525,19 @@
507
525
  </template>
508
526
  <v-row dense align="center">
509
527
  <v-col cols="2">
510
- <v-btn class="bg-office" @click="emits('back')">
528
+ <v-btn class="bg-office" @click="onBack">
511
529
  BACK
512
530
  <v-icon icon="$back"></v-icon>
513
531
  </v-btn>
514
532
  </v-col>
515
533
  <v-col cols="2">
516
- <v-btn :disabled="!optionsChanged && !toolsChanged" class="bg-office" @click="onSave">
534
+ <v-btn :disabled="!optionsChanged && !toolsChanged" class="bg-office" @click="onSave(true)">
517
535
  SAVE
518
536
  <v-icon icon="$save"></v-icon>
519
537
  </v-btn>
520
538
  </v-col>
521
539
  <v-col cols="2">
522
- <v-btn :disabled="!useChanged" class="bg-office" @click="onSaveUsage">
540
+ <v-btn :disabled="!useChanged" class="bg-office" @click="onSaveUsage(true)">
523
541
  SAVE TOOL USE
524
542
  <v-icon icon="$save"></v-icon>
525
543
  </v-btn>
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { inject, reactive, computed, ref, StyleValue } from 'vue';
2
+ import { inject, reactive, computed, ref, onBeforeUnmount, StyleValue } from 'vue';
3
3
  import { IDataItem, Dictionary, IComparisonFilter, ICompoundFilter, IOpenAIFilter, ITool } from '@christianriedl/utils'
4
4
  import SettingsLine from '../components/SettingsLine.vue';
5
5
 
@@ -12,6 +12,8 @@
12
12
  const numvs = props.vsmetadata.length;
13
13
  const tools = reactive<Dictionary<boolean>>({});
14
14
 
15
+ onBeforeUnmount(() => onBack());
16
+
15
17
  for (const key in props.alltools) {
16
18
  tools[key] = props.tools ? props.tools.indexOf(key) >= 0 : false;
17
19
  }