ninegrid2 6.547.0 → 6.550.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/dist/ai/aiContainer.js +34 -36
- package/dist/ai/aiSettings.js +2 -2
- package/dist/bundle.cjs.js +36 -40
- package/dist/bundle.esm.js +36 -40
- package/package.json +1 -1
- package/src/ai/aiContainer.js +34 -36
- package/src/ai/aiSettings.js +2 -2
package/dist/ai/aiContainer.js
CHANGED
|
@@ -124,6 +124,11 @@ class aiContainer extends HTMLElement
|
|
|
124
124
|
}
|
|
125
125
|
};
|
|
126
126
|
|
|
127
|
+
#extractJsonSnippet = (text) => {
|
|
128
|
+
const match = text.match(/```json([\s\S]*?)```/);
|
|
129
|
+
return match ? match[1].trim() : text;
|
|
130
|
+
};
|
|
131
|
+
|
|
127
132
|
|
|
128
133
|
#generateQdrantFilter = async () => {
|
|
129
134
|
|
|
@@ -161,43 +166,35 @@ class aiContainer extends HTMLElement
|
|
|
161
166
|
Qdrant 필터 JSON:
|
|
162
167
|
`;
|
|
163
168
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
]);
|
|
170
|
-
|
|
171
|
-
console.log(response);
|
|
172
|
-
|
|
173
|
-
let filterString = response.content.trim();
|
|
174
|
-
if (filterString.startsWith("```json")) {
|
|
175
|
-
filterString = filterString.replace("```json", "");
|
|
176
|
-
const idx = filterString.indexOf("```");
|
|
177
|
-
if (idx > 0) {
|
|
178
|
-
filterString = filterString.substring(0, idx);
|
|
179
|
-
//console.log(filterString.substring(idx+3));
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
//filterString = filterString.replaceAll('"value"', '"text"')
|
|
183
|
-
console.log("Generated Filter String:", filterString);
|
|
184
|
-
|
|
185
|
-
// Gemini가 JSON 모드나 Structured Output을 지원하지 않는 경우, 직접 파싱 시도
|
|
186
|
-
// 안정적인 JSON 파싱을 위해 'JSON Mode' 또는 Function Calling 사용을 강력히 권장
|
|
187
|
-
// LangChain의 SelfQueryRetriever를 사용하면 이 부분을 자동화할 수 있습니다.
|
|
188
|
-
//try {
|
|
189
|
-
return JSON.parse(filterString);
|
|
190
|
-
//} catch (parseError) {
|
|
191
|
-
// console.error("Failed to parse filter string as JSON:", parseError);
|
|
192
|
-
// console.error("String that failed to parse:", filterString);
|
|
193
|
-
// return null; // 파싱 실패 시 null 반환 또는 적절한 에러 처리
|
|
194
|
-
//}
|
|
169
|
+
|
|
170
|
+
const response = await this.#model.invoke([
|
|
171
|
+
new SystemMessage(systemMessage),
|
|
172
|
+
new HumanMessage(prompt),
|
|
173
|
+
]);
|
|
195
174
|
|
|
196
|
-
|
|
175
|
+
const elSettings = this.shadowRoot.querySelector("nx-ai-settings");
|
|
176
|
+
if (!elSettings) throw new Error("nx-ai-settings missing !!!");
|
|
197
177
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
178
|
+
console.log(response);
|
|
179
|
+
|
|
180
|
+
let filterString;
|
|
181
|
+
switch (elSettings.server) {
|
|
182
|
+
case "openai":
|
|
183
|
+
filterString = this.#extractJsonSnippet(response.content.trim());
|
|
184
|
+
break;
|
|
185
|
+
case "gemini":
|
|
186
|
+
filterString = this.#extractJsonSnippet(response.content.trim());
|
|
187
|
+
break;
|
|
188
|
+
case "ollama":
|
|
189
|
+
filterString = this.#extractJsonSnippet(response);
|
|
190
|
+
break;
|
|
191
|
+
default:
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
//console.log(filterString);
|
|
196
|
+
|
|
197
|
+
return JSON.parse(filterString);
|
|
201
198
|
}
|
|
202
199
|
|
|
203
200
|
#searchWithQdrantFilter = async (filter) => {
|
|
@@ -244,6 +241,7 @@ class aiContainer extends HTMLElement
|
|
|
244
241
|
|
|
245
242
|
#q1 = async () => {
|
|
246
243
|
const filter = await this.#generateQdrantFilter();
|
|
244
|
+
console.log(filter);
|
|
247
245
|
const searchResults = ninegrid.filter(this.#getData(), filter);
|
|
248
246
|
|
|
249
247
|
await this.#answer(searchResults);
|
|
@@ -251,6 +249,7 @@ class aiContainer extends HTMLElement
|
|
|
251
249
|
|
|
252
250
|
#q2 = async () => {
|
|
253
251
|
const filter = await this.#generateQdrantFilter();
|
|
252
|
+
console.log(filter);
|
|
254
253
|
const searchResults = await this.#searchWithQdrantFilter(filter);
|
|
255
254
|
|
|
256
255
|
await this.#answer(searchResults);
|
|
@@ -360,7 +359,6 @@ class aiContainer extends HTMLElement
|
|
|
360
359
|
|
|
361
360
|
const elAiChat = this.shadowRoot.querySelector("nx-ai-chat");
|
|
362
361
|
|
|
363
|
-
|
|
364
362
|
elAiChat.add("me", question);
|
|
365
363
|
elAiChat.add("ing", question);
|
|
366
364
|
|
package/dist/ai/aiSettings.js
CHANGED
|
@@ -102,10 +102,10 @@ class aiSettings extends HTMLElement
|
|
|
102
102
|
<label><input name="server" type="radio" value="openai">Open AI</label>
|
|
103
103
|
<label><input name="server" type="radio" value="ollama">Ollama</label>
|
|
104
104
|
</div>
|
|
105
|
-
<div class="line gemini">
|
|
105
|
+
<div class="line gemini" style="display:none;">
|
|
106
106
|
<label>API Key: <input id="geminiApiKey" value="${this.geminiApiKey}"/></label>
|
|
107
107
|
</div>
|
|
108
|
-
<div class="line openai">
|
|
108
|
+
<div class="line openai" style="display:none;">
|
|
109
109
|
<label>API Key: <input id="openaiApiKey" value="${this.openaiApiKey}"/></label>
|
|
110
110
|
</div>
|
|
111
111
|
<div class="line ollama">
|
package/dist/bundle.cjs.js
CHANGED
|
@@ -27620,10 +27620,10 @@ class aiSettings extends HTMLElement
|
|
|
27620
27620
|
<label><input name="server" type="radio" value="openai">Open AI</label>
|
|
27621
27621
|
<label><input name="server" type="radio" value="ollama">Ollama</label>
|
|
27622
27622
|
</div>
|
|
27623
|
-
<div class="line gemini">
|
|
27623
|
+
<div class="line gemini" style="display:none;">
|
|
27624
27624
|
<label>API Key: <input id="geminiApiKey" value="${this.geminiApiKey}"/></label>
|
|
27625
27625
|
</div>
|
|
27626
|
-
<div class="line openai">
|
|
27626
|
+
<div class="line openai" style="display:none;">
|
|
27627
27627
|
<label>API Key: <input id="openaiApiKey" value="${this.openaiApiKey}"/></label>
|
|
27628
27628
|
</div>
|
|
27629
27629
|
<div class="line ollama">
|
|
@@ -54325,6 +54325,11 @@ class aiContainer extends HTMLElement
|
|
|
54325
54325
|
}
|
|
54326
54326
|
};
|
|
54327
54327
|
|
|
54328
|
+
#extractJsonSnippet = (text) => {
|
|
54329
|
+
const match = text.match(/```json([\s\S]*?)```/);
|
|
54330
|
+
return match ? match[1].trim() : text;
|
|
54331
|
+
};
|
|
54332
|
+
|
|
54328
54333
|
|
|
54329
54334
|
#generateQdrantFilter = async () => {
|
|
54330
54335
|
|
|
@@ -54362,43 +54367,33 @@ class aiContainer extends HTMLElement
|
|
|
54362
54367
|
Qdrant 필터 JSON:
|
|
54363
54368
|
`;
|
|
54364
54369
|
|
|
54365
|
-
|
|
54366
|
-
|
|
54367
|
-
|
|
54368
|
-
|
|
54369
|
-
|
|
54370
|
-
|
|
54371
|
-
|
|
54372
|
-
|
|
54373
|
-
|
|
54374
|
-
|
|
54375
|
-
|
|
54376
|
-
|
|
54377
|
-
|
|
54378
|
-
|
|
54379
|
-
|
|
54380
|
-
|
|
54381
|
-
|
|
54382
|
-
|
|
54383
|
-
|
|
54384
|
-
|
|
54385
|
-
|
|
54386
|
-
|
|
54387
|
-
|
|
54388
|
-
|
|
54389
|
-
|
|
54390
|
-
|
|
54391
|
-
|
|
54392
|
-
// console.error("Failed to parse filter string as JSON:", parseError);
|
|
54393
|
-
// console.error("String that failed to parse:", filterString);
|
|
54394
|
-
// return null; // 파싱 실패 시 null 반환 또는 적절한 에러 처리
|
|
54395
|
-
//}
|
|
54396
|
-
|
|
54397
|
-
//} catch (error) {
|
|
54398
|
-
|
|
54399
|
-
// console.error("Error generating Qdrant filter with Gemini:", error);
|
|
54400
|
-
// return null;
|
|
54401
|
-
//}
|
|
54370
|
+
|
|
54371
|
+
const response = await this.#model.invoke([
|
|
54372
|
+
new messages.SystemMessage(systemMessage),
|
|
54373
|
+
new messages.HumanMessage(prompt),
|
|
54374
|
+
]);
|
|
54375
|
+
|
|
54376
|
+
const elSettings = this.shadowRoot.querySelector("nx-ai-settings");
|
|
54377
|
+
if (!elSettings) throw new Error("nx-ai-settings missing !!!");
|
|
54378
|
+
|
|
54379
|
+
console.log(response);
|
|
54380
|
+
|
|
54381
|
+
let filterString;
|
|
54382
|
+
switch (elSettings.server) {
|
|
54383
|
+
case "openai":
|
|
54384
|
+
filterString = this.#extractJsonSnippet(response.content.trim());
|
|
54385
|
+
break;
|
|
54386
|
+
case "gemini":
|
|
54387
|
+
filterString = this.#extractJsonSnippet(response.content.trim());
|
|
54388
|
+
break;
|
|
54389
|
+
case "ollama":
|
|
54390
|
+
filterString = this.#extractJsonSnippet(response);
|
|
54391
|
+
break;
|
|
54392
|
+
}
|
|
54393
|
+
|
|
54394
|
+
//console.log(filterString);
|
|
54395
|
+
|
|
54396
|
+
return JSON.parse(filterString);
|
|
54402
54397
|
}
|
|
54403
54398
|
|
|
54404
54399
|
#searchWithQdrantFilter = async (filter) => {
|
|
@@ -54441,6 +54436,7 @@ class aiContainer extends HTMLElement
|
|
|
54441
54436
|
|
|
54442
54437
|
#q1 = async () => {
|
|
54443
54438
|
const filter = await this.#generateQdrantFilter();
|
|
54439
|
+
console.log(filter);
|
|
54444
54440
|
const searchResults = ninegrid.filter(this.#getData(), filter);
|
|
54445
54441
|
|
|
54446
54442
|
await this.#answer(searchResults);
|
|
@@ -54448,6 +54444,7 @@ class aiContainer extends HTMLElement
|
|
|
54448
54444
|
|
|
54449
54445
|
#q2 = async () => {
|
|
54450
54446
|
const filter = await this.#generateQdrantFilter();
|
|
54447
|
+
console.log(filter);
|
|
54451
54448
|
const searchResults = await this.#searchWithQdrantFilter(filter);
|
|
54452
54449
|
|
|
54453
54450
|
await this.#answer(searchResults);
|
|
@@ -54536,7 +54533,6 @@ class aiContainer extends HTMLElement
|
|
|
54536
54533
|
|
|
54537
54534
|
const elAiChat = this.shadowRoot.querySelector("nx-ai-chat");
|
|
54538
54535
|
|
|
54539
|
-
|
|
54540
54536
|
elAiChat.add("me", question);
|
|
54541
54537
|
elAiChat.add("ing", question);
|
|
54542
54538
|
|
package/dist/bundle.esm.js
CHANGED
|
@@ -27618,10 +27618,10 @@ class aiSettings extends HTMLElement
|
|
|
27618
27618
|
<label><input name="server" type="radio" value="openai">Open AI</label>
|
|
27619
27619
|
<label><input name="server" type="radio" value="ollama">Ollama</label>
|
|
27620
27620
|
</div>
|
|
27621
|
-
<div class="line gemini">
|
|
27621
|
+
<div class="line gemini" style="display:none;">
|
|
27622
27622
|
<label>API Key: <input id="geminiApiKey" value="${this.geminiApiKey}"/></label>
|
|
27623
27623
|
</div>
|
|
27624
|
-
<div class="line openai">
|
|
27624
|
+
<div class="line openai" style="display:none;">
|
|
27625
27625
|
<label>API Key: <input id="openaiApiKey" value="${this.openaiApiKey}"/></label>
|
|
27626
27626
|
</div>
|
|
27627
27627
|
<div class="line ollama">
|
|
@@ -54323,6 +54323,11 @@ class aiContainer extends HTMLElement
|
|
|
54323
54323
|
}
|
|
54324
54324
|
};
|
|
54325
54325
|
|
|
54326
|
+
#extractJsonSnippet = (text) => {
|
|
54327
|
+
const match = text.match(/```json([\s\S]*?)```/);
|
|
54328
|
+
return match ? match[1].trim() : text;
|
|
54329
|
+
};
|
|
54330
|
+
|
|
54326
54331
|
|
|
54327
54332
|
#generateQdrantFilter = async () => {
|
|
54328
54333
|
|
|
@@ -54360,43 +54365,33 @@ class aiContainer extends HTMLElement
|
|
|
54360
54365
|
Qdrant 필터 JSON:
|
|
54361
54366
|
`;
|
|
54362
54367
|
|
|
54363
|
-
|
|
54364
|
-
|
|
54365
|
-
|
|
54366
|
-
|
|
54367
|
-
|
|
54368
|
-
|
|
54369
|
-
|
|
54370
|
-
|
|
54371
|
-
|
|
54372
|
-
|
|
54373
|
-
|
|
54374
|
-
|
|
54375
|
-
|
|
54376
|
-
|
|
54377
|
-
|
|
54378
|
-
|
|
54379
|
-
|
|
54380
|
-
|
|
54381
|
-
|
|
54382
|
-
|
|
54383
|
-
|
|
54384
|
-
|
|
54385
|
-
|
|
54386
|
-
|
|
54387
|
-
|
|
54388
|
-
|
|
54389
|
-
|
|
54390
|
-
// console.error("Failed to parse filter string as JSON:", parseError);
|
|
54391
|
-
// console.error("String that failed to parse:", filterString);
|
|
54392
|
-
// return null; // 파싱 실패 시 null 반환 또는 적절한 에러 처리
|
|
54393
|
-
//}
|
|
54394
|
-
|
|
54395
|
-
//} catch (error) {
|
|
54396
|
-
|
|
54397
|
-
// console.error("Error generating Qdrant filter with Gemini:", error);
|
|
54398
|
-
// return null;
|
|
54399
|
-
//}
|
|
54368
|
+
|
|
54369
|
+
const response = await this.#model.invoke([
|
|
54370
|
+
new SystemMessage(systemMessage),
|
|
54371
|
+
new HumanMessage(prompt),
|
|
54372
|
+
]);
|
|
54373
|
+
|
|
54374
|
+
const elSettings = this.shadowRoot.querySelector("nx-ai-settings");
|
|
54375
|
+
if (!elSettings) throw new Error("nx-ai-settings missing !!!");
|
|
54376
|
+
|
|
54377
|
+
console.log(response);
|
|
54378
|
+
|
|
54379
|
+
let filterString;
|
|
54380
|
+
switch (elSettings.server) {
|
|
54381
|
+
case "openai":
|
|
54382
|
+
filterString = this.#extractJsonSnippet(response.content.trim());
|
|
54383
|
+
break;
|
|
54384
|
+
case "gemini":
|
|
54385
|
+
filterString = this.#extractJsonSnippet(response.content.trim());
|
|
54386
|
+
break;
|
|
54387
|
+
case "ollama":
|
|
54388
|
+
filterString = this.#extractJsonSnippet(response);
|
|
54389
|
+
break;
|
|
54390
|
+
}
|
|
54391
|
+
|
|
54392
|
+
//console.log(filterString);
|
|
54393
|
+
|
|
54394
|
+
return JSON.parse(filterString);
|
|
54400
54395
|
}
|
|
54401
54396
|
|
|
54402
54397
|
#searchWithQdrantFilter = async (filter) => {
|
|
@@ -54439,6 +54434,7 @@ class aiContainer extends HTMLElement
|
|
|
54439
54434
|
|
|
54440
54435
|
#q1 = async () => {
|
|
54441
54436
|
const filter = await this.#generateQdrantFilter();
|
|
54437
|
+
console.log(filter);
|
|
54442
54438
|
const searchResults = ninegrid.filter(this.#getData(), filter);
|
|
54443
54439
|
|
|
54444
54440
|
await this.#answer(searchResults);
|
|
@@ -54446,6 +54442,7 @@ class aiContainer extends HTMLElement
|
|
|
54446
54442
|
|
|
54447
54443
|
#q2 = async () => {
|
|
54448
54444
|
const filter = await this.#generateQdrantFilter();
|
|
54445
|
+
console.log(filter);
|
|
54449
54446
|
const searchResults = await this.#searchWithQdrantFilter(filter);
|
|
54450
54447
|
|
|
54451
54448
|
await this.#answer(searchResults);
|
|
@@ -54534,7 +54531,6 @@ class aiContainer extends HTMLElement
|
|
|
54534
54531
|
|
|
54535
54532
|
const elAiChat = this.shadowRoot.querySelector("nx-ai-chat");
|
|
54536
54533
|
|
|
54537
|
-
|
|
54538
54534
|
elAiChat.add("me", question);
|
|
54539
54535
|
elAiChat.add("ing", question);
|
|
54540
54536
|
|
package/package.json
CHANGED
package/src/ai/aiContainer.js
CHANGED
|
@@ -124,6 +124,11 @@ class aiContainer extends HTMLElement
|
|
|
124
124
|
}
|
|
125
125
|
};
|
|
126
126
|
|
|
127
|
+
#extractJsonSnippet = (text) => {
|
|
128
|
+
const match = text.match(/```json([\s\S]*?)```/);
|
|
129
|
+
return match ? match[1].trim() : text;
|
|
130
|
+
};
|
|
131
|
+
|
|
127
132
|
|
|
128
133
|
#generateQdrantFilter = async () => {
|
|
129
134
|
|
|
@@ -161,43 +166,35 @@ class aiContainer extends HTMLElement
|
|
|
161
166
|
Qdrant 필터 JSON:
|
|
162
167
|
`;
|
|
163
168
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
]);
|
|
170
|
-
|
|
171
|
-
console.log(response);
|
|
172
|
-
|
|
173
|
-
let filterString = response.content.trim();
|
|
174
|
-
if (filterString.startsWith("```json")) {
|
|
175
|
-
filterString = filterString.replace("```json", "");
|
|
176
|
-
const idx = filterString.indexOf("```");
|
|
177
|
-
if (idx > 0) {
|
|
178
|
-
filterString = filterString.substring(0, idx);
|
|
179
|
-
//console.log(filterString.substring(idx+3));
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
//filterString = filterString.replaceAll('"value"', '"text"')
|
|
183
|
-
console.log("Generated Filter String:", filterString);
|
|
184
|
-
|
|
185
|
-
// Gemini가 JSON 모드나 Structured Output을 지원하지 않는 경우, 직접 파싱 시도
|
|
186
|
-
// 안정적인 JSON 파싱을 위해 'JSON Mode' 또는 Function Calling 사용을 강력히 권장
|
|
187
|
-
// LangChain의 SelfQueryRetriever를 사용하면 이 부분을 자동화할 수 있습니다.
|
|
188
|
-
//try {
|
|
189
|
-
return JSON.parse(filterString);
|
|
190
|
-
//} catch (parseError) {
|
|
191
|
-
// console.error("Failed to parse filter string as JSON:", parseError);
|
|
192
|
-
// console.error("String that failed to parse:", filterString);
|
|
193
|
-
// return null; // 파싱 실패 시 null 반환 또는 적절한 에러 처리
|
|
194
|
-
//}
|
|
169
|
+
|
|
170
|
+
const response = await this.#model.invoke([
|
|
171
|
+
new SystemMessage(systemMessage),
|
|
172
|
+
new HumanMessage(prompt),
|
|
173
|
+
]);
|
|
195
174
|
|
|
196
|
-
|
|
175
|
+
const elSettings = this.shadowRoot.querySelector("nx-ai-settings");
|
|
176
|
+
if (!elSettings) throw new Error("nx-ai-settings missing !!!");
|
|
197
177
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
178
|
+
console.log(response);
|
|
179
|
+
|
|
180
|
+
let filterString;
|
|
181
|
+
switch (elSettings.server) {
|
|
182
|
+
case "openai":
|
|
183
|
+
filterString = this.#extractJsonSnippet(response.content.trim());
|
|
184
|
+
break;
|
|
185
|
+
case "gemini":
|
|
186
|
+
filterString = this.#extractJsonSnippet(response.content.trim());
|
|
187
|
+
break;
|
|
188
|
+
case "ollama":
|
|
189
|
+
filterString = this.#extractJsonSnippet(response);
|
|
190
|
+
break;
|
|
191
|
+
default:
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
//console.log(filterString);
|
|
196
|
+
|
|
197
|
+
return JSON.parse(filterString);
|
|
201
198
|
}
|
|
202
199
|
|
|
203
200
|
#searchWithQdrantFilter = async (filter) => {
|
|
@@ -244,6 +241,7 @@ class aiContainer extends HTMLElement
|
|
|
244
241
|
|
|
245
242
|
#q1 = async () => {
|
|
246
243
|
const filter = await this.#generateQdrantFilter();
|
|
244
|
+
console.log(filter);
|
|
247
245
|
const searchResults = ninegrid.filter(this.#getData(), filter);
|
|
248
246
|
|
|
249
247
|
await this.#answer(searchResults);
|
|
@@ -251,6 +249,7 @@ class aiContainer extends HTMLElement
|
|
|
251
249
|
|
|
252
250
|
#q2 = async () => {
|
|
253
251
|
const filter = await this.#generateQdrantFilter();
|
|
252
|
+
console.log(filter);
|
|
254
253
|
const searchResults = await this.#searchWithQdrantFilter(filter);
|
|
255
254
|
|
|
256
255
|
await this.#answer(searchResults);
|
|
@@ -360,7 +359,6 @@ class aiContainer extends HTMLElement
|
|
|
360
359
|
|
|
361
360
|
const elAiChat = this.shadowRoot.querySelector("nx-ai-chat");
|
|
362
361
|
|
|
363
|
-
|
|
364
362
|
elAiChat.add("me", question);
|
|
365
363
|
elAiChat.add("ing", question);
|
|
366
364
|
|
package/src/ai/aiSettings.js
CHANGED
|
@@ -102,10 +102,10 @@ class aiSettings extends HTMLElement
|
|
|
102
102
|
<label><input name="server" type="radio" value="openai">Open AI</label>
|
|
103
103
|
<label><input name="server" type="radio" value="ollama">Ollama</label>
|
|
104
104
|
</div>
|
|
105
|
-
<div class="line gemini">
|
|
105
|
+
<div class="line gemini" style="display:none;">
|
|
106
106
|
<label>API Key: <input id="geminiApiKey" value="${this.geminiApiKey}"/></label>
|
|
107
107
|
</div>
|
|
108
|
-
<div class="line openai">
|
|
108
|
+
<div class="line openai" style="display:none;">
|
|
109
109
|
<label>API Key: <input id="openaiApiKey" value="${this.openaiApiKey}"/></label>
|
|
110
110
|
</div>
|
|
111
111
|
<div class="line ollama">
|