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.
- docoreai-2.3.2/CONTRIBUTING-TESTERS.md +81 -0
- docoreai-2.3.2/DEPLOYMENT.md +25 -0
- docoreai-2.3.2/MANIFEST.in +62 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/PKG-INFO +2 -2
- {docoreai-2.3.0 → docoreai-2.3.2}/README.md +1 -1
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/auto_patch.py +78 -15
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/cli.py +24 -28
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/config/db.py +96 -8
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/init_engine.py +6 -6
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/pth_installer.py +3 -3
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/telemetry_wp.py +2 -1
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/token_auth.py +1 -1
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/agentic_predictor.py +1 -1
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/budget_recommendation.py +52 -30
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/cli_integration.py +1 -1
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/feature_engineering.py +1 -1
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/local_budget_checker.py +4 -4
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/predict.py +2 -2
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/runtime_predictor.py +3 -2
- docoreai-2.3.2/docore_ai/utils/logger.py +129 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docoreai.egg-info/SOURCES.txt +2 -1
- {docoreai-2.3.0 → docoreai-2.3.2}/setup.py +19 -20
- docoreai-2.3.0/MANIFEST.in +0 -41
- docoreai-2.3.0/docore_ai/utils/docoreai_log.csv +0 -333
- docoreai-2.3.0/docore_ai/utils/logger.py +0 -61
- {docoreai-2.3.0 → docoreai-2.3.2}/LICENSE.md +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/api/__init__.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/api/main.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/__init__.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/config/__init__.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/config/init_db_async.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/fusion_log_server.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/model.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/patch_manager.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/patcher.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/prompt_updates/__init__.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/prompt_updates/check_prompt_update.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/prompt_updates/prompt_loader.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/providers/__init__.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/providers/bedrock_adapter.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/providers/ollama.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/proxy.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/runtime/__init__.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/runtime/settings.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/__init__.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/comparator/base.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/comparator/llama_cpp_comparator.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/core/alert_emitter.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/core/confidence_engine.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/core/derived_gate.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/core/governance_dispatcher.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/core/policy.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/detectors/__init__.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/detectors/content_policy.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/detectors/pii_detector.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/export/exporter_map.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/export/sdk_hooks.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/export/sdk_hooks1.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/lineage/fingerprint.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/lineage/lifecycle.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/lineage/tracker.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/semantic/__init__.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/semantic/matcher.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/semantic/sketch.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/semantic/thresholds.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/state/cache.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/state/context.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/state/ttl.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/structure/detector.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/structure/heuristics.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/security/types.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/__init__.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/config.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/dispatcher.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/safe_sender.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/safe_sender1.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/telemetry_local.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/token_utils.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/tracker.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/telemetry/usage_limits.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/test_server.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/__init__.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/ab_test_controller.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/auto_retrain_manager.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/auto_trainer.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/budget_manager.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/config.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/daily_pacing_engine.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/data_extraction.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/drift_detector.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/drift_monitor_service.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/evaluation.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/hourly_patterns.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/monitor.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/performance_tracker.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/phase2_config.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/session_tracker.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/soft_limit_injector.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/tests/test_fetch_budget_api.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/tests/test_phase1.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/tests/test_phase2.1_complete.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/tests/test_phase2.2_live.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/tests/test_phase2_mock.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/tests/test_quick.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/tokenization_learner.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/train/train_model.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/__init__.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/charts/__init__.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/charts/cost_chart.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/charts/daily_spend_chart.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/charts/usage_requests_chart.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/governance_event_log.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/live_tab.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/money_burn_tab.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/phase2_config_tab.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/settings_header.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/text_input.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/toggle.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/components/usage_volume_tab.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/launcher.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/ui/main_window.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/utils/EXTINCT-model_registry.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/utils/__init__.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/utils/budget_sync.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/utils/csv_logger.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/utils/helpers.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/utils/metric_aggregator.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/utils/model_registry_sync.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/utils/run_streamlit_with_shutdown.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/docore_ai/utils/show_app.py +0 -0
- {docoreai-2.3.0 → docoreai-2.3.2}/requirements.txt +0 -0
- {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.
|
|
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
|
-
[](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
|
-
[](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
|
|
354
|
-
session_type
|
|
355
|
-
system_prompt_tokens
|
|
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
|
-
|
|
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',
|
|
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',
|
|
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',
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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',
|
|
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.
|
|
69
|
-
console.
|
|
70
|
-
console.
|
|
71
|
-
console.
|
|
72
|
-
console.
|
|
73
|
-
console.
|
|
74
|
-
#console.
|
|
75
|
-
console.
|
|
76
|
-
console.
|
|
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
|
-
|
|
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.
|
|
457
|
+
console.print(f"[bold blue]DoCoreAI version:[/] [white]{current_version}[/]")
|
|
462
458
|
except PackageNotFoundError:
|
|
463
|
-
console.
|
|
459
|
+
console.print("[red]❌ DoCoreAI is not installed.[/]")
|
|
464
460
|
return
|
|
465
461
|
except Exception as e:
|
|
466
|
-
console.
|
|
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
|
-
|
|
527
|
+
dprint(f"📊 Learning tokenization metrics (min {min_samples} samples per model)...")
|
|
532
528
|
learn_all_model_tokenization(min_samples)
|
|
533
|
-
|
|
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.
|
|
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/
|
|
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
|
-
#
|
|
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
|
-
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|