qalita 2.3.1__tar.gz → 2.3.2__tar.gz

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.
Files changed (100) hide show
  1. {qalita-2.3.1 → qalita-2.3.2}/PKG-INFO +1 -1
  2. {qalita-2.3.1 → qalita-2.3.2}/pyproject.toml +1 -1
  3. {qalita-2.3.1 → qalita-2.3.2}/qalita/internal/utils.py +1 -1
  4. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/blueprints/studio.py +40 -1
  5. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/templates/studio/agent-panel.html +71 -12
  6. {qalita-2.3.1 → qalita-2.3.2}/LICENSE +0 -0
  7. {qalita-2.3.1 → qalita-2.3.2}/docs/README.md +0 -0
  8. {qalita-2.3.1 → qalita-2.3.2}/qalita/__init__.py +0 -0
  9. {qalita-2.3.1 → qalita-2.3.2}/qalita/__main__.py +0 -0
  10. {qalita-2.3.1 → qalita-2.3.2}/qalita/commands/__init__.py +0 -0
  11. {qalita-2.3.1 → qalita-2.3.2}/qalita/commands/agent.py +0 -0
  12. {qalita-2.3.1 → qalita-2.3.2}/qalita/commands/pack.py +0 -0
  13. {qalita-2.3.1 → qalita-2.3.2}/qalita/commands/source.py +0 -0
  14. {qalita-2.3.1 → qalita-2.3.2}/qalita/internal/__init__.py +0 -0
  15. {qalita-2.3.1 → qalita-2.3.2}/qalita/internal/config.py +0 -0
  16. {qalita-2.3.1 → qalita-2.3.2}/qalita/internal/error_patterns.py +0 -0
  17. {qalita-2.3.1 → qalita-2.3.2}/qalita/internal/logger.py +0 -0
  18. {qalita-2.3.1 → qalita-2.3.2}/qalita/internal/request.py +0 -0
  19. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/__init__.py +0 -0
  20. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/app.py +0 -0
  21. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/blueprints/agents.py +0 -0
  22. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/blueprints/context.py +0 -0
  23. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/blueprints/dashboard.py +0 -0
  24. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/blueprints/helpers.py +0 -0
  25. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/blueprints/sources.py +0 -0
  26. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/chatgpt.svg +0 -0
  27. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/claude.png +0 -0
  28. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/favicon.ico +0 -0
  29. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/gemini.png +0 -0
  30. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/logo-no-slogan.png +0 -0
  31. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/logo-white-no-slogan.svg +0 -0
  32. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/mistral.svg +0 -0
  33. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/noise.webp +0 -0
  34. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/ollama.png +0 -0
  35. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/platform.png +0 -0
  36. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/alloy-db.png +0 -0
  37. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/amazon-athena.png +0 -0
  38. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/amazon-rds.png +0 -0
  39. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/api.svg +0 -0
  40. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/avro.svg +0 -0
  41. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/azure-database-mysql.png +0 -0
  42. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/azure-database-postgresql.png +0 -0
  43. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/azure-sql-database.png +0 -0
  44. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/azure-sql-managed-instance.png +0 -0
  45. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/azure-synapse-analytics.png +0 -0
  46. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/azure_blob.svg +0 -0
  47. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/bigquery.png +0 -0
  48. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/cassandra.svg +0 -0
  49. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/clickhouse.png +0 -0
  50. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/cloud-sql.png +0 -0
  51. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/cockroach-db.png +0 -0
  52. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/csv.svg +0 -0
  53. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/database.svg +0 -0
  54. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/databricks.png +0 -0
  55. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/duckdb.png +0 -0
  56. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/elasticsearch.svg +0 -0
  57. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/excel.svg +0 -0
  58. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/file.svg +0 -0
  59. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/folder.svg +0 -0
  60. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/gcs.png +0 -0
  61. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/hdfs.svg +0 -0
  62. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/ibm-db2.png +0 -0
  63. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/json.png +0 -0
  64. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/maria-db.png +0 -0
  65. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/mongodb.svg +0 -0
  66. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/mssql.svg +0 -0
  67. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/mysql.svg +0 -0
  68. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/oracle.svg +0 -0
  69. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/parquet.svg +0 -0
  70. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/picture.png +0 -0
  71. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/postgresql.svg +0 -0
  72. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/questdb.png +0 -0
  73. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/redshift.png +0 -0
  74. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/s3.svg +0 -0
  75. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/sap-hana.png +0 -0
  76. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/sftp.png +0 -0
  77. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/single-store.png +0 -0
  78. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/snowflake.png +0 -0
  79. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/sqlite.svg +0 -0
  80. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/sqlserver.png +0 -0
  81. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/starburst.png +0 -0
  82. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/stream.png +0 -0
  83. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/teradata.png +0 -0
  84. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/timescale.png +0 -0
  85. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/xls.svg +0 -0
  86. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/xlsx.svg +0 -0
  87. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/sources-logos/yugabyte-db.png +0 -0
  88. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/studio-logo.svg +0 -0
  89. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/studio.css +0 -0
  90. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/studio.png +0 -0
  91. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/public/styles.css +0 -0
  92. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/templates/dashboard.html +0 -0
  93. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/templates/navbar.html +0 -0
  94. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/templates/sources/added.html +0 -0
  95. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/templates/sources/edit.html +0 -0
  96. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/templates/sources/select-source.html +0 -0
  97. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/templates/studio/context-panel.html +0 -0
  98. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/templates/studio/index.html +0 -0
  99. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/templates/studio/navbar.html +0 -0
  100. {qalita-2.3.1 → qalita-2.3.2}/qalita/web/templates/studio/view-panel.html +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qalita
3
- Version: 2.3.1
3
+ Version: 2.3.2
4
4
  Summary: QALITA Platform Command Line Interface
5
5
  License-File: LICENSE
6
6
  Author: QALITA SAS
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "qalita"
3
- version = "2.3.1"
3
+ version = "2.3.2"
4
4
  description = "QALITA Platform Command Line Interface"
5
5
  authors = ["QALITA SAS <contact@qalita.io>"]
6
6
  readme = "docs/README.md"
@@ -14,7 +14,7 @@ logger = init_logging()
14
14
 
15
15
 
16
16
  def get_version():
17
- return "2.3.1"
17
+ return "2.3.2"
18
18
 
19
19
 
20
20
  def make_tarfile(output_filename, source_dir):
@@ -111,6 +111,17 @@ def _augment_prompt_with_context(prompt: str, issue_id: str | None, source_id: s
111
111
  return meta + base
112
112
 
113
113
 
114
+ def _cloud_enabled() -> bool:
115
+ """Return whether Studio cloud providers are enabled via env flag.
116
+
117
+ Env: QALITA_STUDIO_ENABLE_CLOUD = 1|true|yes|on to enable. Default: disabled.
118
+ """
119
+ try:
120
+ raw = str(os.getenv("QALITA_STUDIO_ENABLE_CLOUD", "0") or "").strip().lower()
121
+ return raw in ("1", "true", "yes", "on")
122
+ except Exception:
123
+ return False
124
+
114
125
  def _studio_conv_dir() -> str:
115
126
  """Return the conversations directory, ensuring it exists."""
116
127
  root = _qalita_home()
@@ -261,8 +272,16 @@ def studio_status():
261
272
  current_provider = next(iter(data["providers"].keys()))
262
273
  except Exception:
263
274
  current_provider = None
275
+ # Enforce local-only when cloud is disabled
276
+ if not _cloud_enabled() and current_provider and current_provider != "local":
277
+ current_provider = "local"
264
278
  return jsonify(
265
- {"configured": exists, "config": data, "current_provider": current_provider}
279
+ {
280
+ "configured": exists,
281
+ "config": data,
282
+ "current_provider": current_provider,
283
+ "cloud_enabled": _cloud_enabled(),
284
+ }
266
285
  )
267
286
 
268
287
 
@@ -294,6 +313,15 @@ def studio_save_config():
294
313
  )
295
314
  set_current = bool(payload.get("set_current"))
296
315
  if provider and conf is not None:
316
+ # Block saving non-local provider when cloud is disabled
317
+ if provider != "local" and not _cloud_enabled():
318
+ return (
319
+ jsonify({
320
+ "ok": False,
321
+ "message": "Cloud providers are disabled. Set QALITA_STUDIO_ENABLE_CLOUD=1 to enable.",
322
+ }),
323
+ 403,
324
+ )
297
325
  providers[provider] = conf
298
326
  if set_current:
299
327
  current["current_provider"] = provider
@@ -367,11 +395,14 @@ def list_providers():
367
395
  {"id": "claude", "name": "Claude", "logo": "/static/sources-logos/api.svg"},
368
396
  {"id": "gemini", "name": "Gemini", "logo": "/static/sources-logos/api.svg"},
369
397
  ]
398
+ if not _cloud_enabled():
399
+ available = [it for it in available if it.get("id") == "local"]
370
400
  return jsonify(
371
401
  {
372
402
  "available": available,
373
403
  "current": current,
374
404
  "configs": providers,
405
+ "cloud_enabled": _cloud_enabled(),
375
406
  }
376
407
  )
377
408
 
@@ -383,6 +414,14 @@ def check_remote():
383
414
  Body: { "provider": "openai"|"mistral", "api_key": "...", "model": "..." }
384
415
  Returns: { ok: bool, message?: str, provider: str }
385
416
  """
417
+ if not _cloud_enabled():
418
+ return (
419
+ jsonify({
420
+ "ok": False,
421
+ "message": "Cloud providers are disabled. Set QALITA_STUDIO_ENABLE_CLOUD=1 to enable.",
422
+ }),
423
+ 403,
424
+ )
386
425
  data = request.get_json(silent=True) or {}
387
426
  provider = (data.get("provider") or "").strip().lower()
388
427
  api_key = (data.get("api_key") or "").strip()
@@ -311,6 +311,8 @@
311
311
  const r = await fetch('/studio/status');
312
312
  const j = await r.json();
313
313
  lastStatus = j;
314
+ // Rebuild provider options depending on cloud flag
315
+ setProviderOptions(!!j.cloud_enabled);
314
316
  const current = j.current_provider || 'local';
315
317
  if (providerSelect) providerSelect.value = current;
316
318
  updateProviderUI(current, j);
@@ -410,6 +412,38 @@
410
412
  } catch (e) { if (msg) msg.textContent = 'Connectivity failed'; }
411
413
  }
412
414
 
415
+ function setProviderOptions(cloudEnabled) {
416
+ try {
417
+ if (!providerSelect) return;
418
+ // Desired list depending on cloud flag
419
+ var desired = cloudEnabled ? [
420
+ { v: 'local', t: 'Ollama' },
421
+ { v: 'openai', t: 'ChatGPT' },
422
+ { v: 'mistral', t: 'Mistral' },
423
+ { v: 'claude', t: 'Claude' },
424
+ { v: 'gemini', t: 'Gemini' }
425
+ ] : [
426
+ { v: 'local', t: 'Ollama' }
427
+ ];
428
+ // If options already match, skip rebuild (lightweight check by values set)
429
+ var currentValues = Array.prototype.map.call(providerSelect.options || [], function (o) { return o && o.value; });
430
+ var desiredValues = desired.map(function (d) { return d.v; });
431
+ var equal = currentValues.length === desiredValues.length && currentValues.every(function (v, i) { return v === desiredValues[i]; });
432
+ if (!equal) {
433
+ providerSelect.innerHTML = '';
434
+ desired.forEach(function (d) {
435
+ var opt = document.createElement('option');
436
+ opt.value = d.v; opt.textContent = d.t;
437
+ providerSelect.appendChild(opt);
438
+ });
439
+ }
440
+ // Force selection to local if cloud is disabled
441
+ if (!cloudEnabled) {
442
+ providerSelect.value = 'local';
443
+ }
444
+ } catch (e) { /* noop */ }
445
+ }
446
+
413
447
  function updateProviderUI(provider, statusObj) {
414
448
  // Update logo
415
449
  let src = '/static/ollama.png';
@@ -421,15 +455,29 @@
421
455
  if (providerLogoInline) { providerLogoInline.src = src; providerLogoInline.alt = alt; }
422
456
  if (providerLogoRemote) { providerLogoRemote.src = src; providerLogoRemote.alt = alt; }
423
457
  // Toggle setup cards
458
+ var cloudEnabled = !!(statusObj && statusObj.cloud_enabled);
459
+ if (provider !== 'local' && !cloudEnabled) {
460
+ // Force local UI when cloud disabled
461
+ provider = 'local';
462
+ if (providerSelect) providerSelect.value = 'local';
463
+ }
424
464
  if (provider === 'local') {
425
465
  const isConfigured = !!(statusObj && statusObj.configured);
426
466
  elOnboarding.style.display = isConfigured ? 'none' : 'block';
427
467
  elRemote.style.display = 'none';
428
468
  elChat.style.display = isConfigured ? 'block' : 'none';
429
469
  } else {
430
- elOnboarding.style.display = 'none';
431
- elRemote.style.display = 'block';
432
- elChat.style.display = 'none';
470
+ // Only show remote setup when cloud is enabled
471
+ if (cloudEnabled) {
472
+ elOnboarding.style.display = 'none';
473
+ elRemote.style.display = 'block';
474
+ elChat.style.display = 'none';
475
+ } else {
476
+ const isConfigured = !!(statusObj && statusObj.configured);
477
+ elOnboarding.style.display = isConfigured ? 'none' : 'block';
478
+ elRemote.style.display = 'none';
479
+ elChat.style.display = isConfigured ? 'block' : 'none';
480
+ }
433
481
  }
434
482
  // Toggle provider-specific help
435
483
  const h11 = document.getElementById('help_openai_1');
@@ -440,14 +488,16 @@
440
488
  const c12 = document.getElementById('help_claude_2');
441
489
  const g11 = document.getElementById('help_gemini_1');
442
490
  const g12 = document.getElementById('help_gemini_2');
443
- if (h11) h11.style.display = provider === 'openai' ? '' : 'none';
444
- if (h12) h12.style.display = provider === 'openai' ? '' : 'none';
445
- if (h21) h21.style.display = provider === 'mistral' ? '' : 'none';
446
- if (h22) h22.style.display = provider === 'mistral' ? '' : 'none';
447
- if (c11) c11.style.display = provider === 'claude' ? '' : 'none';
448
- if (c12) c12.style.display = provider === 'claude' ? '' : 'none';
449
- if (g11) g11.style.display = provider === 'gemini' ? '' : 'none';
450
- if (g12) g12.style.display = provider === 'gemini' ? '' : 'none';
491
+ var showHelp = function (cond) { return cond ? '' : 'none'; };
492
+ var allowRemoteHelp = cloudEnabled;
493
+ if (h11) h11.style.display = allowRemoteHelp && provider === 'openai' ? '' : 'none';
494
+ if (h12) h12.style.display = allowRemoteHelp && provider === 'openai' ? '' : 'none';
495
+ if (h21) h21.style.display = allowRemoteHelp && provider === 'mistral' ? '' : 'none';
496
+ if (h22) h22.style.display = allowRemoteHelp && provider === 'mistral' ? '' : 'none';
497
+ if (c11) c11.style.display = allowRemoteHelp && provider === 'claude' ? '' : 'none';
498
+ if (c12) c12.style.display = allowRemoteHelp && provider === 'claude' ? '' : 'none';
499
+ if (g11) g11.style.display = allowRemoteHelp && provider === 'gemini' ? '' : 'none';
500
+ if (g12) g12.style.display = allowRemoteHelp && provider === 'gemini' ? '' : 'none';
451
501
  }
452
502
 
453
503
  // --- Source pre-prompt helpers ---
@@ -717,7 +767,14 @@
717
767
  btnSave && btnSave.addEventListener('click', saveStudio);
718
768
  (document.getElementById('btn_save_remote')) && document.getElementById('btn_save_remote').addEventListener('click', saveRemote);
719
769
  (document.getElementById('btn_check_remote')) && document.getElementById('btn_check_remote').addEventListener('click', checkRemote);
720
- providerSelect && providerSelect.addEventListener('change', function () { updateProviderUI(providerSelect.value, lastStatus); });
770
+ providerSelect && providerSelect.addEventListener('change', function () {
771
+ try {
772
+ var cloudEnabled = !!(lastStatus && lastStatus.cloud_enabled);
773
+ var target = cloudEnabled ? providerSelect.value : 'local';
774
+ if (providerSelect.value !== target) providerSelect.value = target;
775
+ updateProviderUI(target, lastStatus);
776
+ } catch (e) { updateProviderUI('local', lastStatus); }
777
+ });
721
778
  send && send.addEventListener('click', sendMessage);
722
779
  stop && stop.addEventListener('click', function () { if (streamingController) { try { streamingController.abort(); } catch (e) { } } });
723
780
  input && input.addEventListener('keydown', function (e) { if (e.key === 'Enter') sendMessage(); });
@@ -747,6 +804,8 @@
747
804
  });
748
805
 
749
806
  renderAgentTabs();
807
+ // Default to local-only providers until status says otherwise
808
+ try { setProviderOptions(false); } catch (e) { }
750
809
  refreshStatus();
751
810
  checkOllama();
752
811
  // Load conversation if present in URL
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes