@veolab/discoverylab 0.1.9 → 1.0.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/chunk-FPHD7HSQ.js +6812 -0
- package/dist/chunk-KUFBCBNJ.js +6815 -0
- package/dist/chunk-L5IJZV5F.js +6822 -0
- package/dist/chunk-V3CBINLD.js +6812 -0
- package/dist/chunk-VPYSLEGM.js +6710 -0
- package/dist/cli.js +1 -1
- package/dist/index.html +91 -14
- package/dist/index.js +1 -1
- package/dist/server-LCPB2L4U.js +13 -0
- package/dist/server-MKVK6ZQQ.js +13 -0
- package/dist/server-ONSKQO4W.js +13 -0
- package/dist/server-Q4FBWQUA.js +13 -0
- package/dist/server-UJB44EW5.js +13 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -11,7 +11,7 @@ program.command("serve").description("Start the DiscoveryLab web UI server").opt
|
|
|
11
11
|
console.log(chalk.cyan("\n DiscoveryLab"));
|
|
12
12
|
console.log(chalk.gray(" AI-powered app testing & evidence generator\n"));
|
|
13
13
|
try {
|
|
14
|
-
const { startServer } = await import("./server-
|
|
14
|
+
const { startServer } = await import("./server-Q4FBWQUA.js");
|
|
15
15
|
await startServer(port);
|
|
16
16
|
console.log(chalk.green(` Server running at http://localhost:${port}`));
|
|
17
17
|
console.log(chalk.gray(" Press Ctrl+C to stop\n"));
|
package/dist/index.html
CHANGED
|
@@ -6965,7 +6965,7 @@
|
|
|
6965
6965
|
<option value="auto">Auto (priority order)</option>
|
|
6966
6966
|
</select>
|
|
6967
6967
|
<div style="font-size: 10px; color: var(--text-muted); margin-top: 4px;">
|
|
6968
|
-
Auto: Anthropic → OpenAI → Claude CLI
|
|
6968
|
+
Auto: Anthropic → OpenAI → Ollama → Claude CLI
|
|
6969
6969
|
</div>
|
|
6970
6970
|
</div>
|
|
6971
6971
|
<div class="setting-item">
|
|
@@ -7017,6 +7017,18 @@
|
|
|
7017
7017
|
</optgroup>
|
|
7018
7018
|
</select>
|
|
7019
7019
|
</div>
|
|
7020
|
+
<div class="setting-item">
|
|
7021
|
+
<label class="setting-label">Claude CLI Model (Local)</label>
|
|
7022
|
+
<select class="setting-input" id="claudeCliModel" style="cursor: pointer;">
|
|
7023
|
+
<option value="haiku">Haiku 4.5 · Fastest for quick answers (default)</option>
|
|
7024
|
+
<option value="sonnet">Sonnet · Better reasoning/coding (higher cost)</option>
|
|
7025
|
+
<option value="opus">Opus · Most capable (higher cost)</option>
|
|
7026
|
+
<option value="opus[1m]">Opus 1M · Long context beta (requires access)</option>
|
|
7027
|
+
</select>
|
|
7028
|
+
<div style="font-size: 10px; color: var(--text-muted); margin-top: 4px;">
|
|
7029
|
+
Haiku 4.5 is the best default for DiscoveryLab: fast, lower cost, and works with image/vision flows.
|
|
7030
|
+
</div>
|
|
7031
|
+
</div>
|
|
7020
7032
|
<div class="setting-item">
|
|
7021
7033
|
<label class="setting-label">Ollama URL (Local - Free)</label>
|
|
7022
7034
|
<div style="display: flex; gap: 8px;">
|
|
@@ -8056,6 +8068,44 @@
|
|
|
8056
8068
|
|
|
8057
8069
|
// LLM Settings
|
|
8058
8070
|
let currentOllamaModel = 'llama3.2';
|
|
8071
|
+
const LLM_AUTO_PROVIDER_PRIORITY = ['anthropic', 'openai', 'ollama', 'claude-cli'];
|
|
8072
|
+
|
|
8073
|
+
function normalizeOllamaModelName(value) {
|
|
8074
|
+
return String(value || '').trim().toLowerCase();
|
|
8075
|
+
}
|
|
8076
|
+
|
|
8077
|
+
function ollamaModelNamesMatch(installedName, selectedName) {
|
|
8078
|
+
const installed = normalizeOllamaModelName(installedName);
|
|
8079
|
+
const selected = normalizeOllamaModelName(selectedName);
|
|
8080
|
+
if (!installed || !selected) return false;
|
|
8081
|
+
if (installed === selected) return true;
|
|
8082
|
+
return installed.split(':')[0] === selected.split(':')[0];
|
|
8083
|
+
}
|
|
8084
|
+
|
|
8085
|
+
function resolveLLMProviderStatus(data) {
|
|
8086
|
+
const providers = Array.isArray(data?.providers) ? data.providers : [];
|
|
8087
|
+
const preferredProvider = data?.preferredProvider || 'auto';
|
|
8088
|
+
const byKey = new Map(providers.map(p => [p.key, p]));
|
|
8089
|
+
const isReady = (p) => !!(p && p.available && p.configured);
|
|
8090
|
+
|
|
8091
|
+
const resolveAuto = () => {
|
|
8092
|
+
for (const key of LLM_AUTO_PROVIDER_PRIORITY) {
|
|
8093
|
+
const candidate = byKey.get(key);
|
|
8094
|
+
if (isReady(candidate)) return candidate;
|
|
8095
|
+
}
|
|
8096
|
+
return null;
|
|
8097
|
+
};
|
|
8098
|
+
|
|
8099
|
+
if (preferredProvider && preferredProvider !== 'auto') {
|
|
8100
|
+
const preferred = byKey.get(preferredProvider);
|
|
8101
|
+
if (isReady(preferred)) {
|
|
8102
|
+
return { activeProvider: preferred, fallbackFromPreferred: false };
|
|
8103
|
+
}
|
|
8104
|
+
return { activeProvider: resolveAuto(), fallbackFromPreferred: true, preferredProvider };
|
|
8105
|
+
}
|
|
8106
|
+
|
|
8107
|
+
return { activeProvider: resolveAuto(), fallbackFromPreferred: false };
|
|
8108
|
+
}
|
|
8059
8109
|
|
|
8060
8110
|
async function loadLLMSettings() {
|
|
8061
8111
|
try {
|
|
@@ -8067,6 +8117,7 @@
|
|
|
8067
8117
|
document.getElementById('openaiApiKey').value = data.openaiApiKey || '';
|
|
8068
8118
|
document.getElementById('openaiModel').value = data.openaiModel || 'gpt-5.2';
|
|
8069
8119
|
document.getElementById('ollamaUrl').value = data.ollamaUrl || 'http://localhost:11434';
|
|
8120
|
+
document.getElementById('claudeCliModel').value = data.claudeCliModel || 'haiku';
|
|
8070
8121
|
currentOllamaModel = data.ollamaModel || 'llama3.2';
|
|
8071
8122
|
|
|
8072
8123
|
// Update preferred provider dropdown
|
|
@@ -8112,6 +8163,8 @@
|
|
|
8112
8163
|
const container = document.getElementById('ollamaModelSelector');
|
|
8113
8164
|
const badge = document.getElementById('ollamaStatusBadge');
|
|
8114
8165
|
const refreshIcon = document.getElementById('ollamaRefreshIcon');
|
|
8166
|
+
const ollamaUrlInput = document.getElementById('ollamaUrl');
|
|
8167
|
+
const typedOllamaUrl = (ollamaUrlInput?.value || '').trim();
|
|
8115
8168
|
|
|
8116
8169
|
// Show loading state
|
|
8117
8170
|
if (refreshIcon) {
|
|
@@ -8135,7 +8188,8 @@
|
|
|
8135
8188
|
}
|
|
8136
8189
|
|
|
8137
8190
|
try {
|
|
8138
|
-
const
|
|
8191
|
+
const query = typedOllamaUrl ? `?url=${encodeURIComponent(typedOllamaUrl)}` : '';
|
|
8192
|
+
const response = await fetch(`/api/ollama/status${query}`);
|
|
8139
8193
|
const data = await response.json();
|
|
8140
8194
|
|
|
8141
8195
|
if (refreshIcon) {
|
|
@@ -8143,24 +8197,40 @@
|
|
|
8143
8197
|
}
|
|
8144
8198
|
|
|
8145
8199
|
if (data.running && data.models && data.models.length > 0) {
|
|
8200
|
+
const selectedModelAvailable = data.selectedModelAvailable !== false;
|
|
8201
|
+
const selectedModel = data.currentModel || currentOllamaModel || 'llama3.2';
|
|
8202
|
+
|
|
8146
8203
|
// Ollama is running and has models
|
|
8147
8204
|
if (badge) {
|
|
8148
|
-
|
|
8149
|
-
|
|
8150
|
-
|
|
8205
|
+
if (selectedModelAvailable) {
|
|
8206
|
+
badge.textContent = `${data.models.length} model${data.models.length > 1 ? 's' : ''}`;
|
|
8207
|
+
badge.style.background = 'rgba(34, 197, 94, 0.15)';
|
|
8208
|
+
badge.style.color = 'var(--success)';
|
|
8209
|
+
} else {
|
|
8210
|
+
badge.textContent = 'Model missing';
|
|
8211
|
+
badge.style.background = 'rgba(245, 158, 11, 0.15)';
|
|
8212
|
+
badge.style.color = 'var(--warning)';
|
|
8213
|
+
}
|
|
8151
8214
|
}
|
|
8152
8215
|
if (container) {
|
|
8153
8216
|
const modelOptions = data.models.map(m => {
|
|
8154
8217
|
const sizeMB = Math.round(m.size / 1024 / 1024);
|
|
8155
8218
|
const sizeStr = sizeMB > 1024 ? `${(sizeMB / 1024).toFixed(1)}GB` : `${sizeMB}MB`;
|
|
8156
|
-
const selected = m.name
|
|
8219
|
+
const selected = ollamaModelNamesMatch(m.name, selectedModel) ? 'selected' : '';
|
|
8157
8220
|
return `<option value="${m.name}" ${selected}>${m.name} (${sizeStr})</option>`;
|
|
8158
8221
|
}).join('');
|
|
8159
8222
|
|
|
8160
8223
|
container.innerHTML = `
|
|
8161
|
-
<
|
|
8162
|
-
|
|
8163
|
-
|
|
8224
|
+
<div style="display: grid; gap: 8px;">
|
|
8225
|
+
<select class="setting-input" id="ollamaModel" style="cursor: pointer;">
|
|
8226
|
+
${modelOptions}
|
|
8227
|
+
</select>
|
|
8228
|
+
${selectedModelAvailable ? '' : `
|
|
8229
|
+
<div style="padding: 8px; background: rgba(245, 158, 11, 0.08); border: 1px solid rgba(245, 158, 11, 0.2); border-radius: 6px; color: var(--warning); font-size: 11px;">
|
|
8230
|
+
Selected model "${selectedModel}" is not installed. Choose an available model and save.
|
|
8231
|
+
</div>
|
|
8232
|
+
`}
|
|
8233
|
+
</div>
|
|
8164
8234
|
`;
|
|
8165
8235
|
}
|
|
8166
8236
|
} else if (data.running) {
|
|
@@ -8229,6 +8299,7 @@
|
|
|
8229
8299
|
anthropicModel: document.getElementById('anthropicModel')?.value || 'claude-sonnet-4-20250514',
|
|
8230
8300
|
openaiApiKey: document.getElementById('openaiApiKey')?.value || '',
|
|
8231
8301
|
openaiModel: document.getElementById('openaiModel')?.value || 'gpt-5.2',
|
|
8302
|
+
claudeCliModel: document.getElementById('claudeCliModel')?.value || 'haiku',
|
|
8232
8303
|
ollamaUrl: document.getElementById('ollamaUrl')?.value || 'http://localhost:11434',
|
|
8233
8304
|
ollamaModel: ollamaModel,
|
|
8234
8305
|
preferredProvider: document.getElementById('preferredProvider')?.value || 'auto'
|
|
@@ -8243,7 +8314,9 @@
|
|
|
8243
8314
|
// Update current model
|
|
8244
8315
|
currentOllamaModel = ollamaModel;
|
|
8245
8316
|
|
|
8246
|
-
|
|
8317
|
+
await checkOllamaStatus();
|
|
8318
|
+
await updatePreferredProviderDropdown(settings.preferredProvider || 'auto');
|
|
8319
|
+
await updateLLMStatus();
|
|
8247
8320
|
} catch (e) {
|
|
8248
8321
|
console.error('Failed to save LLM settings:', e);
|
|
8249
8322
|
}
|
|
@@ -8257,17 +8330,21 @@
|
|
|
8257
8330
|
try {
|
|
8258
8331
|
const response = await fetch('/api/mobile-chat/providers');
|
|
8259
8332
|
const data = await response.json();
|
|
8260
|
-
|
|
8261
|
-
const activeProvider =
|
|
8333
|
+
const resolved = resolveLLMProviderStatus(data);
|
|
8334
|
+
const activeProvider = resolved.activeProvider;
|
|
8262
8335
|
if (activeProvider) {
|
|
8263
8336
|
statusDot.classList.remove('missing');
|
|
8264
8337
|
statusDot.classList.add('installed');
|
|
8265
|
-
statusText.textContent =
|
|
8338
|
+
statusText.textContent = resolved.fallbackFromPreferred
|
|
8339
|
+
? `Preferred unavailable, using ${activeProvider.name}`
|
|
8340
|
+
: `Active: ${activeProvider.name}`;
|
|
8266
8341
|
statusText.style.color = 'var(--success)';
|
|
8267
8342
|
} else {
|
|
8268
8343
|
statusDot.classList.remove('installed');
|
|
8269
8344
|
statusDot.classList.add('missing');
|
|
8270
|
-
statusText.textContent =
|
|
8345
|
+
statusText.textContent = resolved.fallbackFromPreferred
|
|
8346
|
+
? 'Preferred provider unavailable'
|
|
8347
|
+
: 'No provider configured';
|
|
8271
8348
|
statusText.style.color = 'var(--error)';
|
|
8272
8349
|
}
|
|
8273
8350
|
} catch (e) {
|
package/dist/index.js
CHANGED