docoreai 2.3.0__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 (132) hide show
  1. docoreai-2.3.2/CONTRIBUTING-TESTERS.md +81 -0
  2. docoreai-2.3.2/DEPLOYMENT.md +25 -0
  3. docoreai-2.3.2/MANIFEST.in +62 -0
  4. {docoreai-2.3.0 → docoreai-2.3.2}/PKG-INFO +2 -2
  5. {docoreai-2.3.0 → docoreai-2.3.2}/README.md +1 -1
  6. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/auto_patch.py +78 -15
  7. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/cli.py +24 -28
  8. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/config/db.py +96 -8
  9. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/init_engine.py +6 -6
  10. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/pth_installer.py +3 -3
  11. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/telemetry_wp.py +2 -1
  12. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/token_auth.py +1 -1
  13. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/agentic_predictor.py +1 -1
  14. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/budget_recommendation.py +52 -30
  15. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/cli_integration.py +1 -1
  16. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/feature_engineering.py +1 -1
  17. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/local_budget_checker.py +4 -4
  18. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/predict.py +2 -2
  19. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/runtime_predictor.py +3 -2
  20. docoreai-2.3.2/docore_ai/utils/logger.py +129 -0
  21. {docoreai-2.3.0 → docoreai-2.3.2}/docoreai.egg-info/SOURCES.txt +2 -1
  22. {docoreai-2.3.0 → docoreai-2.3.2}/setup.py +19 -20
  23. docoreai-2.3.0/MANIFEST.in +0 -41
  24. docoreai-2.3.0/docore_ai/utils/docoreai_log.csv +0 -333
  25. docoreai-2.3.0/docore_ai/utils/logger.py +0 -61
  26. {docoreai-2.3.0 → docoreai-2.3.2}/LICENSE.md +0 -0
  27. {docoreai-2.3.0 → docoreai-2.3.2}/api/__init__.py +0 -0
  28. {docoreai-2.3.0 → docoreai-2.3.2}/api/main.py +0 -0
  29. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/__init__.py +0 -0
  30. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/config/__init__.py +0 -0
  31. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/config/init_db_async.py +0 -0
  32. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/fusion_log_server.py +0 -0
  33. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/model.py +0 -0
  34. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/patch_manager.py +0 -0
  35. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/patcher.py +0 -0
  36. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/prompt_updates/__init__.py +0 -0
  37. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/prompt_updates/check_prompt_update.py +0 -0
  38. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/prompt_updates/prompt_loader.py +0 -0
  39. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/providers/__init__.py +0 -0
  40. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/providers/bedrock_adapter.py +0 -0
  41. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/providers/ollama.py +0 -0
  42. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/proxy.py +0 -0
  43. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/runtime/__init__.py +0 -0
  44. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/runtime/settings.py +0 -0
  45. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/__init__.py +0 -0
  46. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/comparator/base.py +0 -0
  47. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/comparator/llama_cpp_comparator.py +0 -0
  48. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/core/alert_emitter.py +0 -0
  49. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/core/confidence_engine.py +0 -0
  50. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/core/derived_gate.py +0 -0
  51. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/core/governance_dispatcher.py +0 -0
  52. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/core/policy.py +0 -0
  53. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/detectors/__init__.py +0 -0
  54. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/detectors/content_policy.py +0 -0
  55. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/detectors/pii_detector.py +0 -0
  56. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/export/exporter_map.py +0 -0
  57. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/export/sdk_hooks.py +0 -0
  58. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/export/sdk_hooks1.py +0 -0
  59. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/lineage/fingerprint.py +0 -0
  60. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/lineage/lifecycle.py +0 -0
  61. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/lineage/tracker.py +0 -0
  62. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/semantic/__init__.py +0 -0
  63. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/semantic/matcher.py +0 -0
  64. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/semantic/sketch.py +0 -0
  65. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/semantic/thresholds.py +0 -0
  66. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/state/cache.py +0 -0
  67. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/state/context.py +0 -0
  68. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/state/ttl.py +0 -0
  69. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/structure/detector.py +0 -0
  70. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/structure/heuristics.py +0 -0
  71. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/types.py +0 -0
  72. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/__init__.py +0 -0
  73. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/config.py +0 -0
  74. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/dispatcher.py +0 -0
  75. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/safe_sender.py +0 -0
  76. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/safe_sender1.py +0 -0
  77. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/telemetry_local.py +0 -0
  78. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/token_utils.py +0 -0
  79. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/tracker.py +0 -0
  80. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/usage_limits.py +0 -0
  81. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/test_server.py +0 -0
  82. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/__init__.py +0 -0
  83. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/ab_test_controller.py +0 -0
  84. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/auto_retrain_manager.py +0 -0
  85. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/auto_trainer.py +0 -0
  86. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/budget_manager.py +0 -0
  87. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/config.py +0 -0
  88. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/daily_pacing_engine.py +0 -0
  89. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/data_extraction.py +0 -0
  90. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/drift_detector.py +0 -0
  91. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/drift_monitor_service.py +0 -0
  92. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/evaluation.py +0 -0
  93. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/hourly_patterns.py +0 -0
  94. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/monitor.py +0 -0
  95. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/performance_tracker.py +0 -0
  96. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/phase2_config.py +0 -0
  97. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/session_tracker.py +0 -0
  98. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/soft_limit_injector.py +0 -0
  99. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/tests/test_fetch_budget_api.py +0 -0
  100. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/tests/test_phase1.py +0 -0
  101. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/tests/test_phase2.1_complete.py +0 -0
  102. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/tests/test_phase2.2_live.py +0 -0
  103. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/tests/test_phase2_mock.py +0 -0
  104. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/tests/test_quick.py +0 -0
  105. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/tokenization_learner.py +0 -0
  106. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/train_model.py +0 -0
  107. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/__init__.py +0 -0
  108. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/charts/__init__.py +0 -0
  109. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/charts/cost_chart.py +0 -0
  110. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/charts/daily_spend_chart.py +0 -0
  111. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/charts/usage_requests_chart.py +0 -0
  112. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/governance_event_log.py +0 -0
  113. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/live_tab.py +0 -0
  114. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/money_burn_tab.py +0 -0
  115. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/phase2_config_tab.py +0 -0
  116. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/settings_header.py +0 -0
  117. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/text_input.py +0 -0
  118. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/toggle.py +0 -0
  119. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/usage_volume_tab.py +0 -0
  120. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/launcher.py +0 -0
  121. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/main_window.py +0 -0
  122. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/utils/EXTINCT-model_registry.py +0 -0
  123. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/utils/__init__.py +0 -0
  124. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/utils/budget_sync.py +0 -0
  125. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/utils/csv_logger.py +0 -0
  126. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/utils/helpers.py +0 -0
  127. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/utils/metric_aggregator.py +0 -0
  128. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/utils/model_registry_sync.py +0 -0
  129. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/utils/run_streamlit_with_shutdown.py +0 -0
  130. {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/utils/show_app.py +0 -0
  131. {docoreai-2.3.0 → docoreai-2.3.2}/requirements.txt +0 -0
  132. {docoreai-2.3.0 → docoreai-2.3.2}/setup.cfg +0 -0
@@ -0,0 +1,81 @@
1
+ # 🧪 Contributing as a Tester
2
+
3
+ Thank you for your interest in testing **DoCoreAI**!
4
+ Your feedback is vital to improving our platform and shaping the future of intelligent prompt optimization.
5
+
6
+ > 💡 DoCoreAI is licensed under **CC BY-NC-ND 4.0**, which restricts direct code contributions or modifications.
7
+ > However, **we welcome feedback, test results, and creative feature ideas from our testers**.
8
+
9
+ ---
10
+
11
+ ## 🎁 Free Pro Plan for Valid Testers
12
+
13
+ We're offering **complimentary Pro plan access** (SaaS version of DoCoreAI) to testers who meet the following criteria:
14
+
15
+ ✅ Sign up for the **free trial plan** at [https://docoreai.com/register/](https://docoreai.com/register/)
16
+ ✅ Perform real-world testing using your own prompts and scenarios
17
+ ✅ Submit any **valid bugs**, **creative feature suggestions**, or **meaningful usability feedback**
18
+
19
+ 📨 Send your feedback to **info@docoreai.com** with subject: `Testing Feedback – Pro Plan Request`
20
+
21
+ ---
22
+
23
+ ## 🚀 What You’ll Be Doing
24
+
25
+ - 🧠 Compare DoCoreAI's responses with standard LLM outputs
26
+ - 🧪 Evaluate prompt optimization accuracy, token savings, and efficiency
27
+ - 💡 Suggest feature ideas or interface improvements
28
+ - 🐞 Report any issues, bugs, or edge cases
29
+
30
+ ---
31
+
32
+ ## 📝 How to Get Started
33
+
34
+ ### 1. Install the CLI Tester
35
+
36
+ Install Python if not already installed: https://www.python.org/downloads/
37
+
38
+ In your terminal, run:
39
+
40
+ ```
41
+ pip install docoreai
42
+
43
+ ```
44
+ ---
45
+
46
+ Download sample test script: https://github.com/SajiJohnMiranda/DoCoreAI/blob/main/tests/Quick%20Test/test.py
47
+
48
+ ---
49
+
50
+ ### 2. Create a .env file in your test directory:
51
+
52
+ ```
53
+ # .env
54
+ OPENAI_API_KEY="your-openai-api-key"
55
+ GROQ_API_KEY="your-groq-api-key"
56
+ MODEL_PROVIDER="openai" # Choose 'openai' or 'groq'
57
+ MODEL_NAME="gpt-3.5-turbo" # Or use groq model: gemma2-9b-it
58
+
59
+ ```
60
+
61
+ ### 3. Run Your Test
62
+ ```
63
+ python test.py
64
+
65
+ ```
66
+
67
+ ---
68
+ ## 🗣️ How to Share Feedback
69
+ Choose one or more of the following:
70
+
71
+ - ✉️ Email your bugs and suggestions to: info@docoreai.com
72
+
73
+ - 🐛 Open a GitHub Issue if your feedback applies to the public CLI - https://github.com/SajiJohnMiranda/DoCoreAI/discussions
74
+
75
+ ---
76
+ ## 🙌 Thank You
77
+ Your testing helps ensure DoCoreAI performs reliably across models and use cases.
78
+ Together, we’re improving how developers interact with LLMs.
79
+
80
+ For quick support, contact:
81
+ 📧 info@docoreai.com
@@ -0,0 +1,25 @@
1
+ ## Required Environment Variable
2
+
3
+ DOCOREAI_ENV_PATH must be set before `docoreai start` runs.
4
+ It must point to the directory containing the client app and SQLite DB.
5
+
6
+ ### Docker
7
+ ENV DOCOREAI_ENV_PATH=/app
8
+
9
+ ### docker-compose
10
+ environment:
11
+ - DOCOREAI_ENV_PATH=/app
12
+
13
+ ### Kubernetes
14
+ env:
15
+ - name: DOCOREAI_ENV_PATH
16
+ value: /app
17
+
18
+ If not set, DoCoreAI falls back to the home directory,
19
+ which may cause incorrect SQLite resolution in containers.
20
+
21
+ > **Note for non-root container users:** If the container runs as a non-root user, ensure that user has write access to the Python `site-packages` directory, or install DoCoreAI with the `--user` flag:
22
+ > ```
23
+ > pip install docoreai --user
24
+ > ```
25
+ > This ensures `docoreai start` can write the `.pth` file without permission errors.
@@ -0,0 +1,62 @@
1
+ # ── Include essential root files ──────────────────────────────────────────
2
+ include README.md
3
+ include LICENSE.md
4
+ include CONTRIBUTING-TESTERS.md
5
+ include DEPLOYMENT.md
6
+ include requirements.txt
7
+ include setup.py
8
+ include MANIFEST.in
9
+
10
+ # ── Include package data files ────────────────────────────────────────────
11
+
12
+ # ── New files added in v2.2.0 ─────────────────────────────────────────────
13
+ include docore_ai/providers/__init__.py
14
+ include docore_ai/providers/bedrock_adapter.py
15
+ include docore_ai/train/hourly_patterns.py
16
+ include docore_ai/train/session_tracker.py
17
+ include docore_ai/patch_manager.py
18
+
19
+ # ── Include all Python source ─────────────────────────────────────────────
20
+ recursive-include docore_ai *.py
21
+ recursive-include api *.py
22
+
23
+ # ── Exclude development-only directories ─────────────────────────────────
24
+ prune docore_ai/Tests
25
+ prune docore_ai/train/saved_models
26
+ prune docore_ai/train/.cache
27
+ prune .vscode
28
+ prune assets
29
+ prune css
30
+ prune Deleted
31
+ prune dist
32
+ prune build
33
+ prune docoreai.egg-info
34
+ prune evals
35
+ prune templates_docs
36
+ prune .docoreai
37
+ prune docoreai_data
38
+ prune docoreai-test
39
+ prune __pycache__
40
+
41
+ # ── Exclude runtime-generated files ──────────────────────────────────────
42
+ exclude install_path.txt
43
+ exclude docoreai_install_path.txt
44
+ exclude site_path.txt
45
+ exclude docoreai_autopatch.pth
46
+ exclude docore_ai/config.db
47
+ exclude docore_ai/config.db-shm
48
+ exclude docore_ai/config.db-wal
49
+
50
+ # ── Exclude development-only root files ──────────────────────────────────
51
+ exclude .env
52
+ exclude .gitignore
53
+ exclude DoCoreAI.session.sql
54
+ exclude docoreai.spec
55
+ exclude directory.txt
56
+ exclude python-3.13.5.exe
57
+ exclude requirements-dev.txt
58
+
59
+ # ── Exclude Python cache ──────────────────────────────────────────────────
60
+ global-exclude __pycache__/*
61
+ global-exclude *.pyc
62
+ global-exclude *.pyo
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: docoreai
3
- Version: 2.3.0
3
+ Version: 2.3.2
4
4
  Summary: Self-tuning AI budgets, built privacy-first.
5
5
  Home-page: https://docoreai.com
6
6
  Author: Saji John Miranda
@@ -110,7 +110,7 @@ It learns your actual usage patterns. It predicts what each request genuinely ne
110
110
 
111
111
  ## See It in Action
112
112
 
113
- [![DoCoreAI Demo](https://i9.ytimg.com/vi_webp/07C5INF_wCk/mqdefault.webp?v=6a7ab287&sqp=CKzk6tMG&rs=AOn4CLDPILgwtWQ8lG-xHfE7QsbFZA0fHA)](https://youtu.be/07C5INF_wCk)
113
+ [![DoCoreAI Demo](https://docoreai.com/wp-content/uploads/2026/08/ai-cost-governance-token-cost-savings-docoreai-youtube-thumbnail-1.png)](https://youtu.be/07C5INF_wCk)
114
114
 
115
115
  ▶ [Watch the demo on YouTube](https://youtu.be/07C5INF_wCk)
116
116
 
@@ -44,7 +44,7 @@ It learns your actual usage patterns. It predicts what each request genuinely ne
44
44
 
45
45
  ## See It in Action
46
46
 
47
- [![DoCoreAI Demo](https://i9.ytimg.com/vi_webp/07C5INF_wCk/mqdefault.webp?v=6a7ab287&sqp=CKzk6tMG&rs=AOn4CLDPILgwtWQ8lG-xHfE7QsbFZA0fHA)](https://youtu.be/07C5INF_wCk)
47
+ [![DoCoreAI Demo](https://docoreai.com/wp-content/uploads/2026/08/ai-cost-governance-token-cost-savings-docoreai-youtube-thumbnail-1.png)](https://youtu.be/07C5INF_wCk)
48
48
 
49
49
  ▶ [Watch the demo on YouTube](https://youtu.be/07C5INF_wCk)
50
50
 
@@ -341,18 +341,18 @@ def prepare_and_log_telemetry(args, kwargs, response, provider,in_learning_windo
341
341
  role=role,
342
342
  model_name=model_name,
343
343
  execution_time=execution_time,
344
- #prompt_version=state.get("prompt_bundle", {}).get("prompt_version"),
345
344
  prompt_version=PROMPT_CONFIG.get("active_prompt_version"),
346
345
  version_info=get_version_info(),
347
346
  success=True,
348
347
  response_content=response_content,
349
348
  usage=usage,
350
349
  bloat_info=token_profiler(user_content, model_name),
351
- max_tokens=kwargs.get("max_tokens"),
350
+ max_tokens=kwargs.get("max_tokens") or kwargs.get("max_completion_tokens"),
352
351
  mode='T' if in_learning_window else 'L',
353
- session_id = kwargs.get('_docoreai_session_id'),
354
- session_type = kwargs.get('_docoreai_session_type'),
355
- system_prompt_tokens = kwargs.get('_docoreai_system_prompt_tokens', 0),
352
+ session_id = kwargs.get('_docoreai_session_id'),
353
+ session_type = kwargs.get('_docoreai_session_type'),
354
+ system_prompt_tokens = kwargs.get('_docoreai_system_prompt_tokens', 0),
355
+ temperature = kwargs.get('temperature', -1),
356
356
  )
357
357
 
358
358
  # Attach agentic classification (set by make_llm_wrapper via kwargs stash).
@@ -369,6 +369,33 @@ def prepare_and_log_telemetry(args, kwargs, response, provider,in_learning_windo
369
369
  except Exception as e:
370
370
  dprint(f"⚠️ Telemetry failed - Patch: {e}")
371
371
 
372
+ def _get_max_tokens_param(model_name: str) -> str | None:
373
+ """
374
+ Returns the correct API parameter name for injecting the governance
375
+ token ceiling for this model.
376
+
377
+ Returns:
378
+ str — parameter name to use e.g. 'max_tokens', 'max_completion_tokens'
379
+ '' — model supports no token ceiling param (do not inject)
380
+ None — model not in registry (fall back to 'max_tokens')
381
+ """
382
+ try:
383
+ from docore_ai.config.db import get_connection
384
+ conn = get_connection()
385
+ cur = conn.cursor()
386
+ cur.execute(
387
+ "SELECT max_output_tokens_param "
388
+ "FROM wp_docoreai_model_registry "
389
+ "WHERE model_name = ? LIMIT 1",
390
+ (model_name,)
391
+ )
392
+ row = cur.fetchone()
393
+ conn.close()
394
+ if row is not None:
395
+ return row[0] if row[0] is not None else 'max_tokens'
396
+ except Exception:
397
+ pass
398
+ return None # not in registry — caller uses 'max_tokens' fallback
372
399
  # ------------------------------------------------------------
373
400
  # UNIVERSAL WRAPPER (provider bound at patch time)
374
401
  # + GenAI Runtime Governance (Phase-1)
@@ -623,6 +650,7 @@ def make_llm_wrapper(provider):
623
650
  prompt_tokens = 0
624
651
  prompt_length = 0
625
652
  system_prompt_tokens = 0
653
+ _client_max = None # canonical value of what client sent
626
654
 
627
655
  if not messages_list and "_captured_prompt" in kwargs:
628
656
  prompt_text = kwargs["_captured_prompt"]
@@ -678,6 +706,20 @@ def make_llm_wrapper(provider):
678
706
  f"📊 Prompt analysis: {prompt_tokens} total tokens "
679
707
  f"({system_prompt_tokens} system), {prompt_length} chars"
680
708
  )
709
+ # ── Normalize incoming token ceiling params ───────────────────
710
+ # Read whatever the client passed — store as canonical value
711
+ # Then strip ALL known aliases so we inject exactly ONE later
712
+ _client_max = (
713
+ kwargs.get('max_tokens') or
714
+ kwargs.get('max_completion_tokens')
715
+ )
716
+ if _client_max:
717
+ dprint(f"📊 Client requested max tokens: {_client_max} (normalized to canonical)")
718
+ # Remove all known aliases from kwargs now
719
+ # (will inject the correct one after governance decision)
720
+ for _tok_alias in ('max_tokens', 'max_completion_tokens'):
721
+ kwargs.pop(_tok_alias, None)
722
+
681
723
  current_model = kwargs.get("model") or get_state().get("model_name") or "unknown"
682
724
 
683
725
  # Bedrock override — model and prompt are in args, not kwargs
@@ -693,7 +735,7 @@ def make_llm_wrapper(provider):
693
735
  except Exception as _bex:
694
736
  dprint(f"⚠️ Bedrock model/prompt extraction failed: {_bex}")
695
737
 
696
- dprint(f"📊 Prompt analysis: {prompt_tokens} tokens, {prompt_length} chars")
738
+
697
739
 
698
740
  predicted_max_tokens = None
699
741
  governance_max_tokens = None
@@ -830,7 +872,7 @@ def make_llm_wrapper(provider):
830
872
  prompt_tokens=prompt_tokens,
831
873
  prompt_length=prompt_length,
832
874
  model_name=current_model,
833
- temperature=kwargs.get('temperature', 0.7),
875
+ temperature=kwargs.get('temperature', -1),
834
876
  user_id=state.get("user_id"),
835
877
  )
836
878
  except Exception as _agentic_err:
@@ -895,7 +937,7 @@ def make_llm_wrapper(provider):
895
937
  prompt_tokens=prompt_tokens,
896
938
  prompt_length=prompt_length,
897
939
  model_name=current_model,
898
- temperature=kwargs.get('temperature', 0.7),
940
+ temperature=kwargs.get('temperature', -1),
899
941
  )
900
942
  if agentic_ctx and agentic_ctx.call_type == "tool_call":
901
943
  dprint(f"🔗 Agentic tool_call turn — flat estimate: {predicted_max_tokens}")
@@ -911,7 +953,7 @@ def make_llm_wrapper(provider):
911
953
  prompt_tokens=prompt_tokens,
912
954
  prompt_length=prompt_length,
913
955
  model_name=current_model,
914
- temperature=kwargs.get('temperature', 0.7),
956
+ temperature=kwargs.get('temperature', -1),
915
957
  model_version=model_version_to_use,
916
958
  is_agentic=0,
917
959
  call_type='standard',
@@ -1062,7 +1104,8 @@ def make_llm_wrapper(provider):
1062
1104
  # Anthropic mandates max_tokens — preserve the 4096 we injected
1063
1105
  dprint("📚 Training mode: Anthropic set max_tokens=4096 preserved (API requirement)")
1064
1106
  else:
1065
- kwargs.pop('max_tokens', None)
1107
+ for _tok_alias in ('max_tokens', 'max_completion_tokens'):
1108
+ kwargs.pop(_tok_alias, None)
1066
1109
  dprint("📚 Training mode: max_tokens not injected — LLM runs naturally")
1067
1110
  else:
1068
1111
  # Read governance mode from DB config
@@ -1074,7 +1117,7 @@ def make_llm_wrapper(provider):
1074
1117
  except Exception:
1075
1118
  use_client = 'always'
1076
1119
 
1077
- user_sent_max_tokens = kwargs.get('max_tokens')
1120
+ user_sent_max_tokens = _client_max
1078
1121
 
1079
1122
  if use_client == 'never':
1080
1123
  # Governance always wins — client value stripped entirely
@@ -1095,7 +1138,10 @@ def make_llm_wrapper(provider):
1095
1138
  if user_sent_max_tokens:
1096
1139
  final_max_tokens = min(user_sent_max_tokens, governance_max_tokens)
1097
1140
  dprint(f"⚠️ User's app sent max_tokens: {user_sent_max_tokens}")
1098
- dprint(f"🔄 DoCoreAI governance: {user_sent_max_tokens} → {final_max_tokens}")
1141
+ if user_sent_max_tokens > governance_max_tokens:
1142
+ dprint(f"🔄 Client exceeded governance ceiling — capped: {user_sent_max_tokens} → {final_max_tokens}")
1143
+ else:
1144
+ dprint(f"✅ Client value {user_sent_max_tokens} ≤ governance ceiling {governance_max_tokens} — client value used")
1099
1145
  else:
1100
1146
  final_max_tokens = governance_max_tokens
1101
1147
  dprint(f"ℹ️ User's app did NOT send max_tokens")
@@ -1123,7 +1169,23 @@ def make_llm_wrapper(provider):
1123
1169
  except Exception as _binj:
1124
1170
  dprint(f"⚠️ Bedrock max_tokens injection failed: {_binj}")
1125
1171
  else:
1126
- kwargs['max_tokens'] = final_max_tokens
1172
+ # Look up correct param name for this model
1173
+ _param = _get_max_tokens_param(current_model)
1174
+
1175
+ if _param is None:
1176
+ # Not in registry — use safe default
1177
+ _param = 'max_tokens'
1178
+
1179
+ if _param == '':
1180
+ # Model explicitly supports no token ceiling
1181
+ dprint(
1182
+ f"⚠️ Model '{current_model}' does not support "
1183
+ f"token ceiling injection — governance ceiling "
1184
+ f"not applied for this call. "
1185
+ f"Client-requested limit was stripped."
1186
+ )
1187
+ else:
1188
+ kwargs[_param] = final_max_tokens
1127
1189
  except Exception as prediction_error:
1128
1190
  dprint(f"⚠️ Phase 2.2 governance failed: {prediction_error}")
1129
1191
  predicted_max_tokens = None
@@ -1142,7 +1204,8 @@ def make_llm_wrapper(provider):
1142
1204
  # strip it before the Bedrock call — it is injected into args[1] body
1143
1205
  # instead. Passing it as a kwarg causes TypeError in _make_api_call.
1144
1206
  if provider == "bedrock":
1145
- final_kwargs.pop('max_tokens', None)
1207
+ for _tok_alias in ('max_tokens', 'max_completion_tokens'):
1208
+ final_kwargs.pop(_tok_alias, None)
1146
1209
 
1147
1210
  # Strip DoCoreAI-internal telemetry hints — must not reach LLM SDK
1148
1211
  final_kwargs.pop("_docoreai_is_agentic", None)
@@ -1210,7 +1273,7 @@ def make_llm_wrapper(provider):
1210
1273
  model_name=current_model,
1211
1274
  prompt_tokens=prompt_tokens,
1212
1275
  prompt_length=prompt_length,
1213
- temperature=kwargs.get('temperature', 0.7)
1276
+ temperature=kwargs.get('temperature', -1)
1214
1277
  )
1215
1278
  except Exception as track_err:
1216
1279
  dprint(f"⚠️ Prediction tracking failed: {track_err}")
@@ -65,15 +65,15 @@ def run_api_server_in_process():
65
65
  console = Console()
66
66
  def custom_help(ctx: typer.Context, param: typer.CallbackParam, value: bool):
67
67
  if value:
68
- console.print("[bold orange1]🚀 Welcome to DoCoreAI CLI[/]\n")
69
- console.print("[cyan]DoCoreAI helps you optimize prompts, reduce token usage, and view powerful analytics.[/]\n")
70
- console.print("[bold]Available Commands:[/]")
71
- console.print(" [green]start[/] Launch the DoCoreAI proxy")
72
- console.print(" [green]stop[/] Stop the running proxy and clean up")
73
- console.print(" [green]version[/] Show installed version info")
74
- #console.print(" [green]report[/] View analytics dashboard")
75
- console.print("\n📊 Dashboard: https://docoreai.com/dashboard/")
76
- console.print("💬 Help & Issues: https://github.com/SajiJohnMiranda/DoCoreAI/discussions\n")
68
+ console.dprint("[bold orange1]🚀 Welcome to DoCoreAI CLI[/]\n")
69
+ console.dprint("[cyan]DoCoreAI helps you optimize prompts, reduce token usage, and view powerful analytics.[/]\n")
70
+ console.dprint("[bold]Available Commands:[/]")
71
+ console.dprint(" [green]start[/] Launch the DoCoreAI proxy")
72
+ console.dprint(" [green]stop[/] Stop the running proxy and clean up")
73
+ console.dprint(" [green]version[/] Show installed version info")
74
+ #console.dprint(" [green]report[/] View analytics dashboard")
75
+ console.dprint("\n📊 Dashboard: https://docoreai.com/dashboard/")
76
+ console.dprint("💬 Help & Issues: https://github.com/SajiJohnMiranda/DoCoreAI/discussions\n")
77
77
  raise typer.Exit()
78
78
 
79
79
  #IMPORTANT DO NOT IGNORE OR REMOVE THIS BLOCK Option 3: Forced Override + Optional Chaining (Best of Both)
@@ -132,13 +132,13 @@ ENV_FILE = Path.cwd() / ".env"
132
132
  # ✅ Check if API Server is Running (via PID file)
133
133
  @app.command()
134
134
  def start():
135
- dprint("🟢 DoCoreAI CLI start initiated")
135
+ print("🟢 DoCoreAI CLI start initiated")
136
136
 
137
137
  # --- Initialization Phase ---
138
138
  try:
139
- dprint("🔧 Running initialize()...")
139
+ dprint("🔧 Running initialize() in cli...")
140
140
  initialize()
141
- dprint("✅ initialize() complete")
141
+ #dprint("✅ initialize() complete")
142
142
  except Exception as e:
143
143
  dprint(f"❌ initialize() failed: {e}")
144
144
  return
@@ -181,10 +181,6 @@ def start():
181
181
  # --- CLI Banner ---
182
182
  dprint("🔄 Initializing DoCoreAI Engine...")
183
183
  init_db()
184
- # Re-enable governance flag in case a previous stop disabled it.
185
- # apply_patches() also does this but the flag should be set before
186
- # load_telemetry_config() reads it.
187
- #load_telemetry_config()
188
184
 
189
185
  # Sync model registry from server (if needed)
190
186
  _reset_learning_window_if_fresh_db()
@@ -197,7 +193,7 @@ def start():
197
193
  dprint("🔄 Checking model registry sync status...")
198
194
  result = sync_model_registry_from_server(token=token, force=True)
199
195
  if result:
200
- typer.secho("✓ Model registry synced successfully!", fg=typer.colors.GREEN)
196
+ typer.secho("✓ DoCoreAI: Model registry synced successfully!", fg=typer.colors.GREEN)
201
197
  else:
202
198
  typer.secho("❌ Model registry sync failed!", fg=typer.colors.RED,err=True)
203
199
  else:
@@ -458,12 +454,12 @@ def show_version():
458
454
  dprint("------------------------------------------------------------")
459
455
  try:
460
456
  current_version = get_version("docoreai")
461
- console.dprint(f"[bold blue]DoCoreAI version:[/] [white]{current_version}[/]")
457
+ console.print(f"[bold blue]DoCoreAI version:[/] [white]{current_version}[/]")
462
458
  except PackageNotFoundError:
463
- console.dprint("[red]❌ DoCoreAI is not installed.[/]")
459
+ console.print("[red]❌ DoCoreAI is not installed.[/]")
464
460
  return
465
461
  except Exception as e:
466
- console.dprint(f"[bold yellow]⚠️ Could not retrieve version: {e}[/]")
462
+ console.print(f"[bold yellow]⚠️ Could not retrieve version: {e}[/]")
467
463
  return
468
464
  dprint("------------------------------------------------------------")
469
465
  console.print("[bold rgb(244,90,42)]Optimize your prompts, save your tokens![/]")
@@ -528,9 +524,9 @@ def learn_tokenization(min_samples: int = 100):
528
524
  """
529
525
  from docore_ai.train.tokenization_learner import learn_all_model_tokenization
530
526
 
531
- print(f"📊 Learning tokenization metrics (min {min_samples} samples per model)...")
527
+ dprint(f"📊 Learning tokenization metrics (min {min_samples} samples per model)...")
532
528
  learn_all_model_tokenization(min_samples)
533
- print("✅ Tokenization learning complete")
529
+ dprint("✅ Tokenization learning complete")
534
530
 
535
531
  @app.command()
536
532
  def sync():
@@ -545,12 +541,13 @@ def sync():
545
541
  dprint("🔄 Force syncing model registry from server...")
546
542
  result = sync_model_registry_from_server(token=token, force=True)
547
543
  if result:
548
- typer.secho("✓ Model registry synced successfully!", fg=typer.colors.GREEN)
544
+ typer.secho("✓ Model registry synced successfully!", fg=typer.colors.BRIGHT_BLUE)
549
545
  else:
550
546
  typer.secho("❌ Model registry sync failed!", fg=typer.colors.RED,err=True)
551
547
 
552
548
 
553
-
549
+ if __name__ == "__main__":
550
+ app()
554
551
 
555
552
 
556
553
  def ensure_openai_installed(min_version="0.28.1", max_version="2.0.0"):
@@ -735,7 +732,7 @@ def validate_token():
735
732
  dprint("✅ Token validated successfully.")
736
733
  return True
737
734
  else:
738
- dprint("❌ Invalid or expired token. Please reissue from https://docoreai.com/generate-token")
735
+ dprint("❌ Invalid or expired token. Please reissue from https://docoreai.com/account-settings/")
739
736
  return False
740
737
  except Exception as e:
741
738
  dprint(f"⚠️ Error validating token: {e}")
@@ -772,7 +769,7 @@ def quick_account_check():
772
769
  return False
773
770
 
774
771
  user_id = data["user_id"]
775
- #print(user_id)
772
+ #dprint(user_id)
776
773
  except Exception as e:
777
774
  dprint(f"⚠️ Error validating token: {e}")
778
775
  return False
@@ -851,8 +848,7 @@ def clear_training_cache():
851
848
  except Exception as e:
852
849
  dprint(f"⚠️ Could not remove {item}: {e}")
853
850
 
854
- if __name__ == "__main__":
855
- app()
851
+
856
852
 
857
853
  #Retention when added to stop: was throwing error messages in Ctrl+c - To DO Later
858
854
  # session = requests.Session()
@@ -2,6 +2,9 @@ import sqlite3
2
2
  from pathlib import Path
3
3
  from platformdirs import user_config_dir
4
4
  from datetime import datetime, timezone
5
+ import os
6
+ import sys
7
+ import sysconfig
5
8
 
6
9
  from docore_ai.utils.logger import dprint
7
10
 
@@ -23,19 +26,100 @@ PHASE2_CONFIG = {
23
26
  'loaded_at': None,
24
27
  }
25
28
 
29
+
30
+
26
31
  APP_NAME = "DoCoreAI"
27
32
 
28
33
  def get_db_path() -> Path:
29
- config_dir = Path(user_config_dir(APP_NAME))
30
- config_dir.mkdir(parents=True, exist_ok=True)
31
- return config_dir / "config.db"
34
+ try:
35
+ # Get the OS-specific config directory
36
+ config_dir = Path(user_config_dir(APP_NAME))
37
+
38
+ # Print the path so you can verify where it's trying to create the folder
39
+ dprint(f"Attempting to use config directory: {config_dir}")
40
+
41
+ # Create the directory if it doesn't exist
42
+ config_dir.mkdir(parents=True, exist_ok=True)
43
+
44
+ db_path = config_dir / get_installed_db_name()
45
+
46
+ # Create the SQLite database file if it does not exist
47
+ if not db_path.exists():
48
+ dprint(f"Database does not exist. Creating at: {db_path}")
49
+ conn = sqlite3.connect(str(db_path)) # Ensure path is passed as string
50
+ conn.close()
51
+
52
+ return db_path
53
+
54
+ except PermissionError as e:
55
+ dprint(f"PERMISSION ERROR: Cannot write to the config directory.")
56
+ dprint(f"Details: {e}")
57
+ sys.exit(1) # Stop the app since we can't store data
58
+ except Exception as e:
59
+ dprint(f"UNEXPECTED ERROR in get_db_path: {e}")
60
+ sys.exit(1)
32
61
 
33
62
 
34
63
  def get_connection():
35
- conn = sqlite3.connect(get_db_path(), timeout=30)
36
- conn.execute("PRAGMA journal_mode=WAL")
37
- conn.execute("PRAGMA busy_timeout=5000")
38
- return conn
64
+ try:
65
+ db_path = get_db_path()
66
+ conn = sqlite3.connect(str(db_path), timeout=30)
67
+ conn.execute("PRAGMA journal_mode=WAL")
68
+ conn.execute("PRAGMA busy_timeout=5000")
69
+ return conn
70
+ except sqlite3.Error as e:
71
+ dprint(f"SQLITE ERROR: Could not connect to database.")
72
+ dprint(f"Details: {e}")
73
+ sys.exit(1)
74
+ except Exception as e:
75
+ dprint(f"UNEXPECTED ERROR in get_connection: {e}")
76
+ sys.exit(1)
77
+
78
+ def get_installed_db_name(default_name: str = "DoCoreAI") -> str:
79
+ """Reads 'docoreai_install_path.txt' from site-packages and returns
80
+
81
+ the formatted database filename (e.g., 'Multi-Model-with-DoCoreAI.db').
82
+ """
83
+ site_packages_path = sysconfig.get_paths()["purelib"]
84
+ txt_file_path = Path(site_packages_path) / "docoreai_install_path.txt"
85
+
86
+ if txt_file_path.exists():
87
+ # Read text, strip newlines/spaces, and strip trailing slashes (\ or /)
88
+ file_content = txt_file_path.read_text().strip().rstrip("\\/")
89
+
90
+ if file_content:
91
+ folder_name = Path(file_content).name
92
+ return f"{folder_name}.db"
93
+
94
+ return f"{default_name}.db"
95
+
96
+ # def get_db_path() -> Path:
97
+ # """
98
+ # Returns environment-scoped DB path — each Python environment
99
+ # (venv, global, editable) gets its own isolated config.db.
100
+
101
+ # Path: <site-packages>/docore_ai/config.db
102
+ # This means:
103
+ # Global: C:\\Python313\\Lib\\site-packages\\docore_ai\\config.db
104
+ # Venv: C:\\...\\venv\\Lib\\site-packages\\docore_ai\\config.db
105
+ # Editable: C:\\Saji-Projects\\Multi-Model-with-DoCoreAI\\docore_ai\\config.db
106
+ # """
107
+ # import sysconfig
108
+ # package_dir = Path(sysconfig.get_paths()["purelib"])
109
+ # install_path_file = package_dir / "docoreai_install_path.txt"
110
+
111
+ # if install_path_file.exists():
112
+ # install_dir = Path(
113
+ # install_path_file.read_text(encoding="utf-8").strip()
114
+ # )
115
+ # else:
116
+ # install_dir = Path.cwd()
117
+
118
+ # db_dir = install_dir / "db"
119
+ # db_dir.mkdir(parents=True, exist_ok=True)
120
+ # return db_dir / "config.db"
121
+
122
+
39
123
 
40
124
 
41
125
  def init_db():
@@ -98,7 +182,8 @@ def init_db():
98
182
  log_port INTEGER,
99
183
 
100
184
  enabled INTEGER NOT NULL DEFAULT 1,
101
- updated_at TEXT NOT NULL
185
+ updated_at TEXT NOT NULL,
186
+ db_name TEXT
102
187
  )
103
188
  """)
104
189
 
@@ -465,12 +550,15 @@ def init_db():
465
550
  max_output_tokens INTEGER DEFAULT 0,
466
551
  latency_class TEXT,
467
552
  status TEXT DEFAULT 'active',
553
+ max_output_tokens_param TEXT DEFAULT 'max_tokens',
468
554
  notes TEXT,
469
555
  created_at TEXT DEFAULT (datetime('now')),
470
556
  updated_at TEXT DEFAULT (datetime('now'))
471
557
  )
472
558
  """)
473
559
 
560
+
561
+
474
562
  # Create index for fast lookups
475
563
  cur.execute("""
476
564
  CREATE INDEX IF NOT EXISTS idx_model_name