docoreai 2.2.0__tar.gz → 2.3.0__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 (132) hide show
  1. {docoreai-2.2.0 → docoreai-2.3.0}/MANIFEST.in +5 -1
  2. {docoreai-2.2.0 → docoreai-2.3.0}/PKG-INFO +4 -3
  3. {docoreai-2.2.0 → docoreai-2.3.0}/README.md +1 -1
  4. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/auto_patch.py +12 -0
  5. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/cli.py +46 -19
  6. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/init_engine.py +5 -4
  7. docoreai-2.3.0/docore_ai/pth_installer.py +68 -0
  8. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/telemetry/config.py +3 -1
  9. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/telemetry/telemetry_wp.py +1 -1
  10. docoreai-2.3.0/docore_ai/train/__init__.py +13 -0
  11. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/auto_retrain_manager.py +4 -1
  12. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/budget_recommendation.py +2 -3
  13. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/daily_pacing_engine.py +2 -1
  14. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/utils/EXTINCT-model_registry.py +3 -1
  15. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/utils/helpers.py +55 -15
  16. {docoreai-2.2.0 → docoreai-2.3.0}/docoreai.egg-info/SOURCES.txt +0 -2
  17. {docoreai-2.2.0 → docoreai-2.3.0}/requirements.txt +1 -0
  18. {docoreai-2.2.0 → docoreai-2.3.0}/setup.py +73 -37
  19. docoreai-2.2.0/docore_ai/pth_installer.py +0 -117
  20. docoreai-2.2.0/docore_ai/telemetry/.docoreai_usage.json +0 -10
  21. docoreai-2.2.0/docore_ai/train/__init__.py +0 -25
  22. docoreai-2.2.0/docoreai_autopatch.pth +0 -1
  23. {docoreai-2.2.0 → docoreai-2.3.0}/LICENSE.md +0 -0
  24. {docoreai-2.2.0 → docoreai-2.3.0}/api/__init__.py +0 -0
  25. {docoreai-2.2.0 → docoreai-2.3.0}/api/main.py +0 -0
  26. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/__init__.py +0 -0
  27. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/config/__init__.py +0 -0
  28. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/config/db.py +0 -0
  29. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/config/init_db_async.py +0 -0
  30. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/fusion_log_server.py +0 -0
  31. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/model.py +0 -0
  32. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/patch_manager.py +0 -0
  33. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/patcher.py +0 -0
  34. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/prompt_updates/__init__.py +0 -0
  35. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/prompt_updates/check_prompt_update.py +0 -0
  36. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/prompt_updates/prompt_loader.py +0 -0
  37. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/providers/__init__.py +0 -0
  38. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/providers/bedrock_adapter.py +0 -0
  39. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/providers/ollama.py +0 -0
  40. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/proxy.py +0 -0
  41. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/runtime/__init__.py +0 -0
  42. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/runtime/settings.py +0 -0
  43. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/__init__.py +0 -0
  44. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/comparator/base.py +0 -0
  45. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/comparator/llama_cpp_comparator.py +0 -0
  46. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/core/alert_emitter.py +0 -0
  47. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/core/confidence_engine.py +0 -0
  48. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/core/derived_gate.py +0 -0
  49. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/core/governance_dispatcher.py +0 -0
  50. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/core/policy.py +0 -0
  51. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/detectors/__init__.py +0 -0
  52. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/detectors/content_policy.py +0 -0
  53. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/detectors/pii_detector.py +0 -0
  54. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/export/exporter_map.py +0 -0
  55. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/export/sdk_hooks.py +0 -0
  56. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/export/sdk_hooks1.py +0 -0
  57. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/lineage/fingerprint.py +0 -0
  58. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/lineage/lifecycle.py +0 -0
  59. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/lineage/tracker.py +0 -0
  60. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/semantic/__init__.py +0 -0
  61. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/semantic/matcher.py +0 -0
  62. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/semantic/sketch.py +0 -0
  63. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/semantic/thresholds.py +0 -0
  64. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/state/cache.py +0 -0
  65. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/state/context.py +0 -0
  66. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/state/ttl.py +0 -0
  67. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/structure/detector.py +0 -0
  68. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/structure/heuristics.py +0 -0
  69. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/security/types.py +0 -0
  70. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/telemetry/__init__.py +0 -0
  71. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/telemetry/dispatcher.py +0 -0
  72. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/telemetry/safe_sender.py +0 -0
  73. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/telemetry/safe_sender1.py +0 -0
  74. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/telemetry/telemetry_local.py +0 -0
  75. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/telemetry/token_auth.py +0 -0
  76. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/telemetry/token_utils.py +0 -0
  77. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/telemetry/tracker.py +0 -0
  78. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/telemetry/usage_limits.py +0 -0
  79. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/test_server.py +0 -0
  80. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/ab_test_controller.py +0 -0
  81. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/agentic_predictor.py +0 -0
  82. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/auto_trainer.py +0 -0
  83. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/budget_manager.py +0 -0
  84. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/cli_integration.py +0 -0
  85. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/config.py +0 -0
  86. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/data_extraction.py +0 -0
  87. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/drift_detector.py +0 -0
  88. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/drift_monitor_service.py +0 -0
  89. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/evaluation.py +0 -0
  90. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/feature_engineering.py +0 -0
  91. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/hourly_patterns.py +0 -0
  92. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/local_budget_checker.py +0 -0
  93. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/monitor.py +0 -0
  94. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/performance_tracker.py +0 -0
  95. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/phase2_config.py +0 -0
  96. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/predict.py +0 -0
  97. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/runtime_predictor.py +0 -0
  98. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/session_tracker.py +0 -0
  99. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/soft_limit_injector.py +0 -0
  100. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/tests/test_fetch_budget_api.py +0 -0
  101. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/tests/test_phase1.py +0 -0
  102. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/tests/test_phase2.1_complete.py +0 -0
  103. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/tests/test_phase2.2_live.py +0 -0
  104. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/tests/test_phase2_mock.py +0 -0
  105. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/tests/test_quick.py +0 -0
  106. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/tokenization_learner.py +0 -0
  107. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/train/train_model.py +0 -0
  108. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/ui/__init__.py +0 -0
  109. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/ui/components/charts/__init__.py +0 -0
  110. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/ui/components/charts/cost_chart.py +0 -0
  111. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/ui/components/charts/daily_spend_chart.py +0 -0
  112. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/ui/components/charts/usage_requests_chart.py +0 -0
  113. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/ui/components/governance_event_log.py +0 -0
  114. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/ui/components/live_tab.py +0 -0
  115. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/ui/components/money_burn_tab.py +0 -0
  116. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/ui/components/phase2_config_tab.py +0 -0
  117. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/ui/components/settings_header.py +0 -0
  118. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/ui/components/text_input.py +0 -0
  119. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/ui/components/toggle.py +0 -0
  120. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/ui/components/usage_volume_tab.py +0 -0
  121. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/ui/launcher.py +0 -0
  122. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/ui/main_window.py +0 -0
  123. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/utils/__init__.py +0 -0
  124. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/utils/budget_sync.py +0 -0
  125. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/utils/csv_logger.py +0 -0
  126. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/utils/docoreai_log.csv +0 -0
  127. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/utils/logger.py +0 -0
  128. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/utils/metric_aggregator.py +0 -0
  129. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/utils/model_registry_sync.py +0 -0
  130. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/utils/run_streamlit_with_shutdown.py +0 -0
  131. {docoreai-2.2.0 → docoreai-2.3.0}/docore_ai/utils/show_app.py +0 -0
  132. {docoreai-2.2.0 → docoreai-2.3.0}/setup.cfg +0 -0
@@ -6,7 +6,11 @@ include setup.py
6
6
  include MANIFEST.in
7
7
  include docore_ai/prompt_updates/data/*.enc
8
8
  include docore_ai/prompt_updates/data/*.sig
9
-
9
+ include docore_ai/providers/__init__.py
10
+ include docore_ai/providers/bedrock_adapter.py
11
+ include docore_ai/train/hourly_patterns.py
12
+ include docore_ai/train/session_tracker.py
13
+ include docore_ai/patch_manager.py
10
14
 
11
15
  include docore_ai/telemetry/.docoreai_usage.json
12
16
  include docore_ai/utils/docoreai_log.csv
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: docoreai
3
- Version: 2.2.0
3
+ Version: 2.3.0
4
4
  Summary: Self-tuning AI budgets, built privacy-first.
5
5
  Home-page: https://docoreai.com
6
6
  Author: Saji John Miranda
@@ -12,7 +12,7 @@ Project-URL: Blog Post, https://mobilights.medium.com/intelligent-prompt-optimiz
12
12
  Project-URL: Funding, https://docoreai.com/pricing/
13
13
  Project-URL: Support, https://docoreai.com/contact-us
14
14
  Keywords: llm observability,ai cost control,llm budget management,privacy-first ai,zero prompt storage,ai governance,token tracking,llmops,ai observability,budget pacing,enterprise ai,llm monitoring,prompt monitoring,anthropic,openai,groq,google gemini,ollama,llm cost reduction,ai spending,docoreai
15
- Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Development Status :: 4 - Beta
16
16
  Classifier: Programming Language :: Python :: 3.12
17
17
  Classifier: Operating System :: OS Independent
18
18
  Classifier: License :: Other/Proprietary License
@@ -49,6 +49,7 @@ Requires-Dist: packaging>=20.0
49
49
  Requires-Dist: streamlit
50
50
  Requires-Dist: pandas
51
51
  Requires-Dist: streamlit-aggrid
52
+ Requires-Dist: charset-normalizer>=3.0.0
52
53
  Dynamic: author
53
54
  Dynamic: author-email
54
55
  Dynamic: classifier
@@ -72,7 +73,7 @@ Dynamic: summary
72
73
 
73
74
  [![PyPI version](https://img.shields.io/pypi/v/docoreai)](https://pypi.org/project/docoreai/)
74
75
  [![Python](https://img.shields.io/pypi/pyversions/docoreai)](https://pypi.org/project/docoreai/)
75
- [![Downloads](https://static.pepy.tech/badge/docoreai?period=total)](https://pypi.org/project/docoreai/)
76
+ [![Downloads](https://static.pepy.tech/badge/docoreai)](https://pepy.tech/projects/docoreai)
76
77
  [![License: CC BY-NC-ND 4.0](https://img.shields.io/badge/License-CC%20BY--NC--ND%204.0-lightgrey.svg)](https://creativecommons.org/licenses/by-nc-nd/4.0/)
77
78
  [![Status: Early Access](https://img.shields.io/badge/Status-Early%20Access-teal)](https://docoreai.com)
78
79
 
@@ -7,7 +7,7 @@
7
7
 
8
8
  [![PyPI version](https://img.shields.io/pypi/v/docoreai)](https://pypi.org/project/docoreai/)
9
9
  [![Python](https://img.shields.io/pypi/pyversions/docoreai)](https://pypi.org/project/docoreai/)
10
- [![Downloads](https://static.pepy.tech/badge/docoreai?period=total)](https://pypi.org/project/docoreai/)
10
+ [![Downloads](https://static.pepy.tech/badge/docoreai)](https://pepy.tech/projects/docoreai)
11
11
  [![License: CC BY-NC-ND 4.0](https://img.shields.io/badge/License-CC%20BY--NC--ND%204.0-lightgrey.svg)](https://creativecommons.org/licenses/by-nc-nd/4.0/)
12
12
  [![Status: Early Access](https://img.shields.io/badge/Status-Early%20Access-teal)](https://docoreai.com)
13
13
 
@@ -65,11 +65,23 @@ from docore_ai.train.local_budget_checker import check_local_budget, get_todays_
65
65
  # (handles case where client app runs in a separate process from CLI)
66
66
  # ------------------------------------------------------------
67
67
  if not os.environ.get("DOCOREAI_ENV_PATH"):
68
+ # Try bootstrap file written by docoreai start
68
69
  for candidate in [Path.cwd() / ".docoreai_env_path",
69
70
  Path.home() / ".docoreai_env_path"]:
70
71
  if candidate.exists():
71
72
  os.environ["DOCOREAI_ENV_PATH"] = candidate.read_text(encoding="utf-8").strip()
72
73
  break
74
+ # Final fallback — install_path.txt always exists after pip install
75
+ # Final fallback — install_path.txt in repo root
76
+ if not os.environ.get("DOCOREAI_ENV_PATH"):
77
+ try:
78
+ import docore_ai
79
+ import sysconfig
80
+ install_path_file = Path(sysconfig.get_paths()["purelib"]) / "docoreai_install_path.txt"
81
+ if install_path_file.exists():
82
+ os.environ["DOCOREAI_ENV_PATH"] = install_path_file.read_text(encoding="utf-8").strip()
83
+ except Exception:
84
+ pass
73
85
  # ------------------------------------------------------------
74
86
  # ENV bootstrap (UNCHANGED)
75
87
  # ------------------------------------------------------------
@@ -22,7 +22,7 @@ from docore_ai.config.db import TELEMETRY_CONFIG
22
22
 
23
23
  from importlib.metadata import version as get_version, PackageNotFoundError
24
24
  from docore_ai.pth_installer import install_pth_file, blank_pth_file
25
- from docore_ai.utils.helpers import get_docoreai_env_path, is_port_in_use
25
+ from docore_ai.utils.helpers import is_port_in_use
26
26
 
27
27
  from pathlib import Path
28
28
  #from api.main import app as docoreai_api_app
@@ -151,18 +151,10 @@ def start():
151
151
  except Exception as e:
152
152
  dprint(f"⚠️ Auto-training check failed: {e}")
153
153
 
154
- os.environ["DOCOREAI_ENV_PATH"] = str(Path.cwd().resolve())
155
- dprint("Starting DoCoreAI - DOCOREAI_ENV_PATH set to:", os.environ["DOCOREAI_ENV_PATH"])
156
-
157
- # Write it to a small bootstrap file so auto_patch can find it
158
- env_dir = str(Path.cwd().resolve())
159
- for target in [Path.cwd().resolve(), Path.home()]:
160
- try:
161
- (target / ".docoreai_env_path").write_text(env_dir, encoding="utf-8")
162
- dprint(f"📌 Bootstrap path written to: {target / '.docoreai_env_path'}")
163
- except Exception as e:
164
- dprint(f"⚠️ Could not write bootstrap to {target}: {e}")
154
+ #os.environ["DOCOREAI_ENV_PATH"] = get_docoreai_env_path()
155
+ dprint("Starting DoCoreAI - setting .env path to:", Path.cwd() / ".env")
165
156
 
157
+
166
158
  try:
167
159
 
168
160
  ensure_openai_installed()
@@ -365,6 +357,7 @@ def start():
365
357
  stop()
366
358
 
367
359
 
360
+
368
361
  #CLI Command for Manual Retraining:
369
362
  @app.command()
370
363
  def retrain_tokens_model():
@@ -557,8 +550,7 @@ def sync():
557
550
  typer.secho("❌ Model registry sync failed!", fg=typer.colors.RED,err=True)
558
551
 
559
552
 
560
- if __name__ == "__main__":
561
- app()
553
+
562
554
 
563
555
 
564
556
  def ensure_openai_installed(min_version="0.28.1", max_version="2.0.0"):
@@ -654,11 +646,7 @@ def _reset_learning_window_if_fresh_db():
654
646
  except Exception:
655
647
  pass
656
648
 
657
- cache_dir = Path(__file__).parent / 'train' / '.cache'
658
- if cache_dir.exists():
659
- for f in cache_dir.iterdir():
660
- f.unlink()
661
- dprint("🗑️ Training cache cleared")
649
+ clear_training_cache()
662
650
  else:
663
651
  dprint(f"📊 Existing data found ({success_count} records) — learning window state preserved.")
664
652
 
@@ -826,6 +814,45 @@ def quick_account_check():
826
814
  dprint(f"❌ Failed to fetch membership info: {str(e)}")
827
815
 
828
816
 
817
+ from pathlib import Path
818
+ import shutil
819
+
820
+
821
+ def clear_training_cache():
822
+ train_dir = Path(__file__).resolve().parent / "train"
823
+
824
+ for folder_name in ["saved_models", ".cache"]:
825
+ folder = train_dir / folder_name
826
+
827
+ if folder.exists():
828
+ for item in folder.iterdir():
829
+ try:
830
+ if item.is_dir():
831
+ shutil.rmtree(item)
832
+ else:
833
+ item.unlink()
834
+
835
+ dprint(f"🧹 Removed: {item}")
836
+
837
+ except Exception as e:
838
+ dprint(f"⚠️ Could not remove {item}: {e}")
839
+
840
+ from docore_ai.utils.helpers import get_docoreai_data_dir
841
+ data_dir = get_docoreai_data_dir()
842
+
843
+ if data_dir.exists():
844
+ for item in data_dir.iterdir():
845
+ try:
846
+ if item.is_dir():
847
+ shutil.rmtree(item)
848
+ else:
849
+ item.unlink()
850
+ dprint(f"🧹 Removed: {item}")
851
+ except Exception as e:
852
+ dprint(f"⚠️ Could not remove {item}: {e}")
853
+
854
+ if __name__ == "__main__":
855
+ app()
829
856
 
830
857
  #Retention when added to stop: was throwing error messages in Ctrl+c - To DO Later
831
858
  # session = requests.Session()
@@ -56,7 +56,7 @@ def initialize():
56
56
  #ensure_env_file_exists_and_valid() # Depricated as the new version does not require .env file
57
57
 
58
58
  load_dotenv(dotenv_path=dotenv_path, override=True)
59
- dprint(f"📂 .env loaded from: {dotenv_path}")
59
+ dprint(f"📂 Client calling from: {dotenv_path}")
60
60
 
61
61
  _ENGINE_STATE["env_path"] = dotenv_path
62
62
 
@@ -136,7 +136,7 @@ def initialize():
136
136
  resp = session.post(
137
137
  f"{TELEMETRY_CONFIG["api_url"]}/wp-json/docoreai/v1/get_member_info?action=true",
138
138
  json={"user_id": user_id},
139
- timeout=2,
139
+ timeout=5,
140
140
  headers=headers
141
141
  )
142
142
  data = resp.json()
@@ -158,7 +158,8 @@ def initialize():
158
158
  except Exception as e:
159
159
  dprint(f"⚠️ Prompt update failed: {e}")
160
160
  return None
161
-
161
+
162
+ _ENGINE_STATE["initialized"] = True
162
163
  # Execute API calls in parallel (but don't wait for all - fail gracefully)
163
164
  with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
164
165
  # First: validate token (required)
@@ -186,7 +187,7 @@ def initialize():
186
187
  dprint(f"⚠️ Member info fetch failed: {e}")
187
188
 
188
189
 
189
- _ENGINE_STATE["initialized"] = True
190
+ #_ENGINE_STATE["initialized"] = True # remove this
190
191
  dprint("--------------------------------------------------")
191
192
 
192
193
  '''
@@ -0,0 +1,68 @@
1
+ import os
2
+ import subprocess
3
+ import sys
4
+ import sysconfig
5
+ from pathlib import Path
6
+
7
+ from docore_ai.utils.logger import dprint
8
+
9
+ SITE_PACKAGES_PATH = sysconfig.get_paths()["purelib"]
10
+
11
+
12
+ def install_pth_file():
13
+ global SITE_PACKAGES_PATH
14
+
15
+ try:
16
+ if not SITE_PACKAGES_PATH:
17
+ raise ValueError("SITE_PACKAGES_PATH not set")
18
+
19
+ pth_path = os.path.join(SITE_PACKAGES_PATH, "docoreai_autopatch.pth")
20
+
21
+ # Read the project path baked into install_path.txt during pip install.
22
+ # SITE_PACKAGES_PATH is already known, so read directly from there.
23
+ # Falls back to CWD if the file is missing (e.g. dev/editable installs).
24
+ install_path_file = Path(SITE_PACKAGES_PATH) / "docoreai_install_path.txt"
25
+ if install_path_file.exists():
26
+ install_path = install_path_file.read_text(encoding="utf-8").strip()
27
+ else:
28
+ install_path = str(Path.cwd().resolve())
29
+ dprint("⚠️ install_path.txt not found — falling back to CWD")
30
+
31
+ pth_code = (
32
+ f"import os; os.environ.setdefault('DOCOREAI_ENV_PATH', {repr(install_path)}); "
33
+ f"import docore_ai.auto_patch\n"
34
+ )
35
+
36
+ with open(pth_path, "w", encoding="utf-8") as f:
37
+ f.write(pth_code)
38
+
39
+ dprint(f"✅ .pth installed — governance active in client processes from: {install_path}")
40
+
41
+ return True
42
+
43
+ except Exception as e:
44
+ dprint(f"❌ [ERROR] Failed to create .pth file: {e}")
45
+ return False
46
+
47
+
48
+ def blank_pth_file():
49
+ global SITE_PACKAGES_PATH
50
+ try:
51
+ if not SITE_PACKAGES_PATH:
52
+ raise ValueError("SITE_PACKAGES_PATH not set")
53
+
54
+ pth_path = os.path.join(SITE_PACKAGES_PATH, "docoreai_autopatch.pth")
55
+
56
+ if os.path.exists(pth_path):
57
+ with open(pth_path, "w", encoding="utf-8") as f:
58
+ f.write("") # Blank out the file instead of deleting
59
+ else:
60
+ dprint("[INFO] No .pth file found to blank out.")
61
+
62
+ try:
63
+ subprocess.run([sys.executable, "-c", "print('🔕 dopatch is now disabled')"])
64
+ except subprocess.CalledProcessError:
65
+ pass # Silently ignore if subprocess fails
66
+
67
+ except Exception as e:
68
+ dprint(f"❌ [ERROR] Failed to blank out .pth file: {e}")
@@ -12,6 +12,8 @@ load_dotenv(dotenv_path=dotenv_path, override=True)
12
12
  # Configuration variables
13
13
  DOCOREAI_API_URL = TELEMETRY_CONFIG["api_url"] #os.getenv("DOCOREAI_API_URL", "https://docoreai.com")
14
14
  TELEMETRY_ENABLED = TELEMETRY_CONFIG["enabled"] #os.getenv("DOCOREAI_TELEMETRY", "True").strip().lower() in ("true", "1", "yes")
15
- TELEMETRY_LOCAL_FILE = os.getenv("DOCOREAI_LOCAL_FILE", "telemetry_log.json") #TBD
15
+ from docore_ai.utils.helpers import get_docoreai_data_dir as _get_data_dir
16
+ TELEMETRY_LOCAL_FILE = os.getenv("DOCOREAI_LOCAL_FILE", str(_get_data_dir() / "telemetry_log.json"))
17
+
16
18
  DOCOREAI_TOKEN = TELEMETRY_CONFIG["token"] # Sqlite os.getenv("DOCOREAI_TOKEN", "") # Must be set by user
17
19
  ALLOW_SYSTEM_MESSAGE_INJECTION=os.getenv("ALLOW_SYSTEM_MESSAGE_INJECTION")
@@ -163,7 +163,7 @@ def prepare_telemetry_payload(
163
163
  usage = _normalize_usage(usage)
164
164
 
165
165
  payload = {
166
- "user_id": int(user_id),
166
+ "user_id": int(user_id) if user_id is not None else 0,
167
167
  "local_timestamp": datetime.now().astimezone().isoformat(),
168
168
  "prompt_length": len(user_content),
169
169
  "response_length": len(response_content["optimized_response"]) if success and response_content else 0,
@@ -0,0 +1,13 @@
1
+ """
2
+ Max Tokens Prediction Training Module
3
+ """
4
+
5
+ from .runtime_predictor import (get_global_predictor,
6
+ predict_max_tokens,
7
+ reload_predictor,
8
+ get_predictor_info)
9
+
10
+ from .train_model import ModelTrainer
11
+ from .budget_manager import BudgetManager, get_budget_manager
12
+
13
+ __all__ = [...]
@@ -13,6 +13,7 @@ Handles:
13
13
 
14
14
  import json
15
15
  from datetime import datetime, timedelta
16
+ import os
16
17
  from pathlib import Path
17
18
  import threading
18
19
  from docore_ai.config.db import get_phase2_config
@@ -58,7 +59,9 @@ class AutoRetrainingManager:
58
59
  'success_only': get_phase2_config('auto_retrain', 'success_only', _c['data']['success_only']),
59
60
  },
60
61
  }
61
- self.state_file = Path('.docoreai_retrain_state.json')
62
+ from docore_ai.utils.helpers import get_docoreai_data_dir
63
+ self.state_file = get_docoreai_data_dir() / '.docoreai_retrain_state.json'
64
+
62
65
  self.state = self._load_state()
63
66
 
64
67
  def _load_state(self):
@@ -286,9 +286,8 @@ def _get_state_file_path():
286
286
  except Exception:
287
287
  filename = '.docoreai_learning_state.json'
288
288
 
289
- env_path = os.environ.get("DOCOREAI_ENV_PATH")
290
- base = Path(env_path) if env_path else Path.home()
291
- return base / filename
289
+ from docore_ai.utils.helpers import get_docoreai_data_dir
290
+ return get_docoreai_data_dir() / filename
292
291
 
293
292
 
294
293
  def _load_state():
@@ -121,7 +121,8 @@ class DailyPacingEngine:
121
121
 
122
122
  },
123
123
  }
124
- self.cache_file = Path('.docoreai_pacing_cache.json')
124
+ from docore_ai.utils.helpers import get_docoreai_data_dir
125
+ self.cache_file = get_docoreai_data_dir() / '.docoreai_pacing_cache.json'
125
126
  self.patterns = self._load_patterns()
126
127
 
127
128
  def _load_patterns(self):
@@ -8,7 +8,9 @@ import time
8
8
  import requests
9
9
  from pathlib import Path
10
10
 
11
- CACHE_FILE = Path(".docoreai_model_prices.json")
11
+ from docore_ai.utils.helpers import get_docoreai_data_dir as _get_data_dir
12
+ CACHE_FILE = _get_data_dir() / ".docoreai_model_prices.json"
13
+
12
14
  CACHE_TTL_SECONDS = 300 # 5 minutes
13
15
 
14
16
  DEFAULT_FALLBACK = {
@@ -28,23 +28,40 @@ import os
28
28
 
29
29
  from pathlib import Path
30
30
 
31
- def get_docoreai_env_path():
31
+ def get_docoreai_data_dir() -> Path:
32
32
  """
33
- Reads the docoreai_cwd.txt file in the current working directory
34
- and returns the path to the .env file inside that directory.
33
+ Single home folder for all DoCoreAI runtime JSON files.
34
+ Priority:
35
+ 1. DOCOREAI_ENV_PATH env var (container / sysadmin)
36
+ 2. install_path.txt baked into package at pip install time
37
+ 3. Path.home() as last resort
35
38
  """
36
- cwd_file = Path.cwd() / "docoreai_cwd.txt"
37
-
38
- if not cwd_file.exists():
39
- print(f"⚠️ {cwd_file} not found.")
40
- return None
41
-
39
+ # Priority 1 — container or explicit override
40
+ env_path = os.environ.get("DOCOREAI_ENV_PATH")
41
+ if env_path:
42
+ data_dir = Path(env_path) / "docoreai_data"
43
+ data_dir.mkdir(exist_ok=True)
44
+ return data_dir
45
+
46
+ # Priority 2 — install path baked at pip install time
47
+ # Priority 2 — install_path.txt in repo root
42
48
  try:
43
- base_path = Path(cwd_file.read_text(encoding="utf-8").strip()).expanduser().resolve()
44
- return str(Path(base_path) / ".env")
45
- except Exception as e:
46
- print(f"⚠️ Error reading {cwd_file}: {e}")
47
- return None
49
+ import docore_ai
50
+ import sysconfig
51
+ #install_path_file = Path(docore_ai.__file__).parent.parent / "install_path.txt"
52
+ install_path_file = Path(sysconfig.get_paths()["purelib"]) / "docoreai_install_path.txt"
53
+ if install_path_file.exists():
54
+ base = Path(install_path_file.read_text(encoding="utf-8").strip())
55
+ data_dir = base / "docoreai_data"
56
+ data_dir.mkdir(exist_ok=True)
57
+ return data_dir
58
+ except Exception:
59
+ pass
60
+
61
+ # Priority 3 — fallback
62
+ data_dir = Path.home() / "docoreai_data"
63
+ data_dir.mkdir(exist_ok=True)
64
+ return data_dir
48
65
 
49
66
  def get_retry_session(retries=3, backoff_factor=0.5, status_forcelist=(502, 503, 504), session=None):
50
67
  session = session or requests.Session()
@@ -120,4 +137,27 @@ def extract_semantic_role_from_content(content: str) -> str:
120
137
  return extracted_role
121
138
 
122
139
  #dprint("⚠️ No semantic role found in content, defaulting to 'system'")
123
- return "Generalist"
140
+ return "Generalist"
141
+
142
+ '''
143
+ #Depricated
144
+ def get_docoreai_env_path():
145
+ """
146
+ Reads the docoreai_cwd.txt file in the current working directory
147
+ and returns the path to the .env file inside that directory.
148
+ """
149
+ cwd_file = Path.cwd() / "docoreai_cwd.txt"
150
+
151
+ if not cwd_file.exists():
152
+ print(f"⚠️ {cwd_file} not found.")
153
+ return None
154
+
155
+ try:
156
+ base_path = Path(cwd_file.read_text(encoding="utf-8").strip()).expanduser().resolve()
157
+ return str(Path(base_path) / ".env")
158
+ except Exception as e:
159
+ print(f"⚠️ Error reading {cwd_file}: {e}")
160
+ return None
161
+
162
+
163
+ '''
@@ -1,7 +1,6 @@
1
1
  LICENSE.md
2
2
  MANIFEST.in
3
3
  README.md
4
- docoreai_autopatch.pth
5
4
  requirements.txt
6
5
  setup.py
7
6
  api/__init__.py
@@ -55,7 +54,6 @@ docore_ai/security/state/context.py
55
54
  docore_ai/security/state/ttl.py
56
55
  docore_ai/security/structure/detector.py
57
56
  docore_ai/security/structure/heuristics.py
58
- docore_ai/telemetry/.docoreai_usage.json
59
57
  docore_ai/telemetry/__init__.py
60
58
  docore_ai/telemetry/config.py
61
59
  docore_ai/telemetry/dispatcher.py
@@ -30,6 +30,7 @@ importlib-metadata; python_version < "3.8"
30
30
  streamlit
31
31
  pandas
32
32
  streamlit-aggrid
33
+ charset-normalizer>=3.0.0 #need to check if this is really required
33
34
 
34
35
  # For local testing only
35
36
  #openai==1.9.0
@@ -1,6 +1,6 @@
1
1
  import sysconfig
2
2
  from setuptools import setup, find_packages
3
- from setuptools.command.build_py import build_py as build_py_orig
3
+ #from setuptools.command.build_py import build_py as build_py_orig
4
4
  import shutil
5
5
  from pathlib import Path
6
6
  import site
@@ -8,44 +8,81 @@ import sys
8
8
  import os
9
9
  import platform
10
10
 
11
+ # ---------------------------------------------------------
12
+ # Create install_path.txt in the directory where pip runs
13
+ # ---------------------------------------------------------
14
+ INSTALL_PATH_FILE = "install_path.txt"
15
+
16
+ try:
17
+ current_path = os.getcwd()
18
+ install_path_file = os.path.join(current_path, INSTALL_PATH_FILE)
19
+
20
+ with open(install_path_file, "w", encoding="utf-8") as f:
21
+ f.write(current_path)
22
+
23
+ print(f"Created {install_path_file}")
24
+ print(f"Install path: {current_path}")
25
+
26
+ except Exception as e:
27
+ print(f"WARNING: Could not create {INSTALL_PATH_FILE}: {e}")
28
+
29
+
30
+ # ---------------------------------------------------------
31
+ # Create site_path.txt with the Python site-packages path
32
+ # ---------------------------------------------------------
33
+ SITE_PATH_FILE = "site_path.txt"
34
+
35
+ try:
36
+ site_packages_path = sysconfig.get_paths()["purelib"]
37
+ current_path = os.getcwd()
38
+ site_path_file = os.path.join(current_path, SITE_PATH_FILE)
39
+
40
+ with open(site_path_file, "w", encoding="utf-8") as f:
41
+ f.write(site_packages_path)
42
+
43
+ print(f"Created {site_path_file}")
44
+ print(f"Site-packages path: {site_packages_path}")
45
+
46
+ except Exception as e:
47
+ print(f"WARNING: Could not create {SITE_PATH_FILE}: {e}")
48
+
49
+ # ---------------------------------------------------------
50
+ # Create docoreai_autopatch.pth in site-packages
51
+ # ---------------------------------------------------------
11
52
  PTH_FILE = "docoreai_autopatch.pth"
53
+ #INSTALL_PATH_FILE = "docoreai_install_path.txt"
12
54
 
13
- class build_py(build_py_orig):
14
- def run(self):
15
- # First do the normal build
16
- super().run()
17
-
18
- # Now copy the .pth file into the build directory where .py files are placed
19
- if not os.path.exists(PTH_FILE):
20
- print(f"ℹ️ {PTH_FILE} not found. Creating blank file.")
21
- with open(PTH_FILE, "w") as f1:
22
- f1.write("")
23
- # Define target path in build directory
24
- target = os.path.join(self.build_lib, PTH_FILE)
25
- print("build_lib path:", self.build_lib)
26
- # Copy (overwrite if exists)
27
- shutil.copyfile(PTH_FILE, target)
28
- print(f"Copied {PTH_FILE} to {target}")
29
-
30
- site_packages_path = sysconfig.get_paths()["purelib"]
31
- with open("site_path.txt", "w") as f:
32
- f.write(site_packages_path)
33
-
34
- # Save current working directory (where install command was run)
35
- try:
36
- cwd_path = os.getcwd()
37
- with open("docoreai_cwd.txt", "w", encoding="utf-8") as f:
38
- f.write(cwd_path)
39
- print(f"docoreai_cwd.txt written to install path: {cwd_path}")
40
- except Exception as e:
41
- print(f"Failed to write docoreai_cwd.txt: {e}")
55
+ # try:
56
+ # site_packages_path = sysconfig.get_paths()["purelib"]
57
+
58
+ # # Create and copy .pth file
59
+ # if not os.path.exists(PTH_FILE):
60
+ # print(f"Creating source pth {PTH_FILE}")
61
+ # with open(PTH_FILE, "w", encoding="utf-8") as f:
62
+ # f.write("")
63
+ # shutil.copy2(PTH_FILE, os.path.join(site_packages_path, PTH_FILE))
64
+
65
+ # # Create and copy install path file
66
+ # if not os.path.exists(INSTALL_PATH_FILE):
67
+ # print(f"Creating Install Path File {INSTALL_PATH_FILE}")
68
+ # with open(INSTALL_PATH_FILE, "w", encoding="utf-8") as f:
69
+ # f.write(os.getcwd())
70
+ # shutil.copy2(INSTALL_PATH_FILE, os.path.join(site_packages_path, INSTALL_PATH_FILE))
71
+
72
+ # print(f"SUCCESS: Created files in {site_packages_path}")
73
+
74
+ # except Exception as e:
75
+ # print(f"ERROR: {e}")
76
+
42
77
 
43
78
  with open("README.md", "r", encoding="utf-8") as fh:
44
79
  long_description = fh.read()
45
-
80
+
81
+
82
+
46
83
  setup(
47
84
  name="docoreai",
48
- version="2.2.0",
85
+ version="2.3.0",
49
86
  author="Saji John Miranda",
50
87
  author_email="saji.john@docoreai.com",
51
88
  license="CC BY-NC-ND 4.0",
@@ -53,7 +90,7 @@ setup(
53
90
  include=["docore_ai", "docore_ai.*", "api", "api.*"],
54
91
  exclude=["docore_ai.Tests", "docore_ai.Tests.*"],
55
92
  ),
56
- cmdclass={"build_py": build_py},
93
+
57
94
  package_data={
58
95
  "": ["LICENSE.md"],
59
96
  "docore_ai.prompt_updates": ["data/*.enc", "data/*.sig"], # Include encrypted prompt files
@@ -95,10 +132,11 @@ description="Self-tuning AI budgets, built privacy-first.",
95
132
  "streamlit",
96
133
  "pandas",
97
134
  "streamlit-aggrid",
135
+ "charset-normalizer>=3.0.0",
98
136
  ],
99
137
  classifiers=[
100
- # Development stage — Beta is correct for 2.0.0b2
101
- "Development Status :: 3 - Alpha",
138
+ # Development stage
139
+ "Development Status :: 4 - Beta",
102
140
 
103
141
 
104
142
  # Python versions actually supported
@@ -138,6 +176,4 @@ description="Self-tuning AI budgets, built privacy-first.",
138
176
  },
139
177
  include_package_data=True,
140
178
  zip_safe=False,
141
- data_files=[(sysconfig.get_paths()["purelib"], [PTH_FILE])], #31-Jul helps remove pth file in pip uninstall
142
-
143
179
  )