django-explain-errors 0.9.1__tar.gz → 0.9.3__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 (40) hide show
  1. {django_explain_errors-0.9.1/django_explain_errors.egg-info → django_explain_errors-0.9.3}/PKG-INFO +32 -33
  2. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/README.md +25 -32
  3. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3/django_explain_errors.egg-info}/PKG-INFO +32 -33
  4. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/setup.py +7 -1
  5. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/LICENSE +0 -0
  6. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/MANIFEST.in +0 -0
  7. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/django_explain_errors.egg-info/SOURCES.txt +0 -0
  8. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/django_explain_errors.egg-info/dependency_links.txt +0 -0
  9. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/django_explain_errors.egg-info/requires.txt +0 -0
  10. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/django_explain_errors.egg-info/top_level.txt +0 -0
  11. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/explain_errors/__init__.py +0 -0
  12. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/explain_errors/client.py +0 -0
  13. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/explain_errors/debug_page.py +0 -0
  14. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/explain_errors/management/__init__.py +0 -0
  15. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/explain_errors/management/commands/__init__.py +0 -0
  16. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/explain_errors/management/commands/build_error_index.py +0 -0
  17. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/explain_errors/middleware.py +0 -0
  18. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/explain_errors/rag/__init__.py +0 -0
  19. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/explain_errors/rag/indexer.py +0 -0
  20. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/explain_errors/rag/retriever.py +0 -0
  21. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/explain_errors/rag/store.py +0 -0
  22. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/explain_errors/sanitize.py +0 -0
  23. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/explain_errors/throttle.py +0 -0
  24. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/explain_errors/tracebacks.py +0 -0
  25. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/setup.cfg +0 -0
  26. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/tests/test_build_error_index.py +0 -0
  27. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/tests/test_client.py +0 -0
  28. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/tests/test_debug_page.py +0 -0
  29. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/tests/test_eval_fixtures.py +0 -0
  30. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/tests/test_eval_judge.py +0 -0
  31. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/tests/test_eval_run.py +0 -0
  32. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/tests/test_language.py +0 -0
  33. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/tests/test_middleware.py +0 -0
  34. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/tests/test_print_stdout.py +0 -0
  35. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/tests/test_rag.py +0 -0
  36. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/tests/test_sanitize.py +0 -0
  37. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/tests/test_signals.py +0 -0
  38. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/tests/test_throttle.py +0 -0
  39. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/tests/test_tracebacks.py +0 -0
  40. {django_explain_errors-0.9.1 → django_explain_errors-0.9.3}/tests/test_truncation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-explain-errors
3
- Version: 0.9.1
3
+ Version: 0.9.3
4
4
  Summary: Django middleware that explains unhandled exceptions in DEBUG using an LLM, optionally grounded in your own project source via a local vector index. Works with OpenAI, Claude, or any OpenAI-compatible endpoint including local models.
5
5
  Home-page: https://github.com/topunix/django-explain-errors
6
6
  Author: topunix
@@ -9,6 +9,12 @@ License: MIT
9
9
  Classifier: Development Status :: 4 - Beta
10
10
  Classifier: Environment :: Web Environment
11
11
  Classifier: Framework :: Django
12
+ Classifier: Framework :: Django :: 4.2
13
+ Classifier: Framework :: Django :: 5.0
14
+ Classifier: Framework :: Django :: 5.1
15
+ Classifier: Framework :: Django :: 5.2
16
+ Classifier: Framework :: Django :: 6.0
17
+ Classifier: Framework :: Django :: 6.1
12
18
  Classifier: Intended Audience :: Developers
13
19
  Classifier: License :: OSI Approved :: MIT License
14
20
  Classifier: Operating System :: OS Independent
@@ -49,6 +55,7 @@ Explains Django exceptions on the debug page, pointing at the real fix in your o
49
55
  <p align="center">
50
56
  <a href="https://pypi.org/project/django-explain-errors/"><img src="https://img.shields.io/pypi/v/django-explain-errors" alt="PyPI version"></a>
51
57
  <a href="https://pypi.org/project/django-explain-errors/"><img src="https://img.shields.io/pypi/pyversions/django-explain-errors" alt="Python versions"></a>
58
+ <a href="https://pypi.org/project/django-explain-errors/"><img src="https://img.shields.io/pypi/djversions/django-explain-errors" alt="Django versions"></a>
52
59
  <a href="https://github.com/topunix/django-explain-errors/actions/workflows/test.yml"><img src="https://github.com/topunix/django-explain-errors/actions/workflows/test.yml/badge.svg?branch=main" alt="Tests"></a>
53
60
  <a href="https://github.com/topunix/django-explain-errors/blob/main/LICENSE"><img src="https://img.shields.io/pypi/l/django-explain-errors" alt="License"></a>
54
61
  </p>
@@ -539,41 +546,33 @@ django.db.utils.IntegrityError: NOT NULL constraint failed: blog_post.author_id
539
546
 
540
547
  ### Does RAG actually help?
541
548
 
542
- To check whether RAG-grounded explanations are actually better, not just
543
- longer, the package ships an eval harness (`evals/`): fifteen deliberately
544
- broken Django views, each explained twice (once from the traceback alone,
545
- once with RAG enabled) and judged by a separate model, blind to which
546
- explanation is which, against the error's known cause and correct fix
547
- location. Which side the judge sees as "A" is randomized per comparison so
548
- position can't bias the result.
549
-
550
- Across three runs (45 judged comparisons, 2 judge failures, 43 scored),
551
- RAG-on won 35, RAG-off 5, and 3 tied. The gap isn't spread evenly across
552
- everything the judge checks. It's concentrated in whether the explanation
553
- names the right file and function, and whether it invents details along
554
- the way: on `points_to_fix_location`, RAG-on answered yes in 26 of the
555
- group-A comparisons against RAG-off's 13; on `no_fabrication`, 26 against
556
- 17. Without source access, `gpt-4o-mini` tends to invent a
557
- plausible-sounding function name or parameter rather than say it doesn't
558
- know; given the actual code via RAG, it mostly does not.
559
-
560
- Three limitations are worth knowing before trusting this uncritically: RAG
561
- can anchor on the wrong retrieved chunk, as it did in one fixture
562
- (`missing_post_key`) where the fix got redirected to a retrieved template
563
- instead of the view; the judge is shown the failing function's own
564
- source, which is the same source RAG-on's retriever draws from, so part
565
- of RAG-on's `no_fabrication` advantage may be judge and generator
566
- overlapping on material RAG-off never sees rather than RAG-on being more
567
- careful; and claim statuses are spot-checked, not exhaustively audited --
568
- a script that flagged 14 of 363 claims on one run, all correct on manual
569
- inspection, is a sample that turned up no false positive, not a proof
570
- that none exists. Full per-fixture results, the judge prompt, and how to
571
- reproduce this (about $1.37 for a `--runs 3` pass, most of it judge cost)
572
- are in [`evals/README.md`](evals/README.md).
549
+ The package can explain an error in two ways:
550
+
551
+ - **RAG-off (default):** the model sees only the Django traceback.
552
+ - **RAG-on:** the model also sees relevant source code from your project, retrieved from a local index.
553
+
554
+ The eval harness in `evals/` tests whether RAG-on explanations are more accurate, not just longer. It triggers 15 deliberately broken Django views, explains each one both ways, and has a separate judge model compare the two against the error's known cause and fix location. The judge doesn't know which explanation used RAG, and their order is randomized.
555
+
556
+ **Results (3 runs, 43 scored comparisons):** RAG-on won 35, RAG-off won 5, and 3 tied.
557
+
558
+ Most of the gap comes from two checks, measured on the 10 fixtures whose cause is in the app's own code (30 comparisons):
559
+
560
+ - **Points to the right file and function:** RAG-on 26, RAG-off 13
561
+ - **Avoids invented details:** RAG-on 26, RAG-off 17
562
+
563
+ Without your source, gpt-4o-mini tends to invent a plausible function name or parameter rather than admit it doesn't know. With the real code in front of it, it mostly doesn't.
564
+
565
+ **Limitations:**
566
+
567
+ - RAG can retrieve the wrong code. In one fixture (`missing_post_key`), it pointed the fix at a template instead of the view.
568
+ - The judge checks claims against the same source RAG-on retrieves from, which may inflate RAG-on's score for avoiding invented details.
569
+ - Claims are spot-checked, not fully audited. All 14 claims flagged on one run held up on manual review, but that is a sample, not proof.
570
+
571
+ Full results, methodology, and how to reproduce (about $1.37 per `--runs 3` pass) are in [evals/README.md](https://github.com/topunix/django-explain-errors/blob/main/evals/README.md).
573
572
 
574
573
  ## License
575
574
 
576
- This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
575
+ This project is licensed under the MIT License. See the [LICENSE](https://github.com/topunix/django-explain-errors/blob/main/LICENSE) file for details.
577
576
 
578
577
  ## Contributing
579
578
 
@@ -5,6 +5,7 @@ Explains Django exceptions on the debug page, pointing at the real fix in your o
5
5
  <p align="center">
6
6
  <a href="https://pypi.org/project/django-explain-errors/"><img src="https://img.shields.io/pypi/v/django-explain-errors" alt="PyPI version"></a>
7
7
  <a href="https://pypi.org/project/django-explain-errors/"><img src="https://img.shields.io/pypi/pyversions/django-explain-errors" alt="Python versions"></a>
8
+ <a href="https://pypi.org/project/django-explain-errors/"><img src="https://img.shields.io/pypi/djversions/django-explain-errors" alt="Django versions"></a>
8
9
  <a href="https://github.com/topunix/django-explain-errors/actions/workflows/test.yml"><img src="https://github.com/topunix/django-explain-errors/actions/workflows/test.yml/badge.svg?branch=main" alt="Tests"></a>
9
10
  <a href="https://github.com/topunix/django-explain-errors/blob/main/LICENSE"><img src="https://img.shields.io/pypi/l/django-explain-errors" alt="License"></a>
10
11
  </p>
@@ -495,41 +496,33 @@ django.db.utils.IntegrityError: NOT NULL constraint failed: blog_post.author_id
495
496
 
496
497
  ### Does RAG actually help?
497
498
 
498
- To check whether RAG-grounded explanations are actually better, not just
499
- longer, the package ships an eval harness (`evals/`): fifteen deliberately
500
- broken Django views, each explained twice (once from the traceback alone,
501
- once with RAG enabled) and judged by a separate model, blind to which
502
- explanation is which, against the error's known cause and correct fix
503
- location. Which side the judge sees as "A" is randomized per comparison so
504
- position can't bias the result.
505
-
506
- Across three runs (45 judged comparisons, 2 judge failures, 43 scored),
507
- RAG-on won 35, RAG-off 5, and 3 tied. The gap isn't spread evenly across
508
- everything the judge checks. It's concentrated in whether the explanation
509
- names the right file and function, and whether it invents details along
510
- the way: on `points_to_fix_location`, RAG-on answered yes in 26 of the
511
- group-A comparisons against RAG-off's 13; on `no_fabrication`, 26 against
512
- 17. Without source access, `gpt-4o-mini` tends to invent a
513
- plausible-sounding function name or parameter rather than say it doesn't
514
- know; given the actual code via RAG, it mostly does not.
515
-
516
- Three limitations are worth knowing before trusting this uncritically: RAG
517
- can anchor on the wrong retrieved chunk, as it did in one fixture
518
- (`missing_post_key`) where the fix got redirected to a retrieved template
519
- instead of the view; the judge is shown the failing function's own
520
- source, which is the same source RAG-on's retriever draws from, so part
521
- of RAG-on's `no_fabrication` advantage may be judge and generator
522
- overlapping on material RAG-off never sees rather than RAG-on being more
523
- careful; and claim statuses are spot-checked, not exhaustively audited --
524
- a script that flagged 14 of 363 claims on one run, all correct on manual
525
- inspection, is a sample that turned up no false positive, not a proof
526
- that none exists. Full per-fixture results, the judge prompt, and how to
527
- reproduce this (about $1.37 for a `--runs 3` pass, most of it judge cost)
528
- are in [`evals/README.md`](evals/README.md).
499
+ The package can explain an error in two ways:
500
+
501
+ - **RAG-off (default):** the model sees only the Django traceback.
502
+ - **RAG-on:** the model also sees relevant source code from your project, retrieved from a local index.
503
+
504
+ The eval harness in `evals/` tests whether RAG-on explanations are more accurate, not just longer. It triggers 15 deliberately broken Django views, explains each one both ways, and has a separate judge model compare the two against the error's known cause and fix location. The judge doesn't know which explanation used RAG, and their order is randomized.
505
+
506
+ **Results (3 runs, 43 scored comparisons):** RAG-on won 35, RAG-off won 5, and 3 tied.
507
+
508
+ Most of the gap comes from two checks, measured on the 10 fixtures whose cause is in the app's own code (30 comparisons):
509
+
510
+ - **Points to the right file and function:** RAG-on 26, RAG-off 13
511
+ - **Avoids invented details:** RAG-on 26, RAG-off 17
512
+
513
+ Without your source, gpt-4o-mini tends to invent a plausible function name or parameter rather than admit it doesn't know. With the real code in front of it, it mostly doesn't.
514
+
515
+ **Limitations:**
516
+
517
+ - RAG can retrieve the wrong code. In one fixture (`missing_post_key`), it pointed the fix at a template instead of the view.
518
+ - The judge checks claims against the same source RAG-on retrieves from, which may inflate RAG-on's score for avoiding invented details.
519
+ - Claims are spot-checked, not fully audited. All 14 claims flagged on one run held up on manual review, but that is a sample, not proof.
520
+
521
+ Full results, methodology, and how to reproduce (about $1.37 per `--runs 3` pass) are in [evals/README.md](https://github.com/topunix/django-explain-errors/blob/main/evals/README.md).
529
522
 
530
523
  ## License
531
524
 
532
- This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
525
+ This project is licensed under the MIT License. See the [LICENSE](https://github.com/topunix/django-explain-errors/blob/main/LICENSE) file for details.
533
526
 
534
527
  ## Contributing
535
528
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-explain-errors
3
- Version: 0.9.1
3
+ Version: 0.9.3
4
4
  Summary: Django middleware that explains unhandled exceptions in DEBUG using an LLM, optionally grounded in your own project source via a local vector index. Works with OpenAI, Claude, or any OpenAI-compatible endpoint including local models.
5
5
  Home-page: https://github.com/topunix/django-explain-errors
6
6
  Author: topunix
@@ -9,6 +9,12 @@ License: MIT
9
9
  Classifier: Development Status :: 4 - Beta
10
10
  Classifier: Environment :: Web Environment
11
11
  Classifier: Framework :: Django
12
+ Classifier: Framework :: Django :: 4.2
13
+ Classifier: Framework :: Django :: 5.0
14
+ Classifier: Framework :: Django :: 5.1
15
+ Classifier: Framework :: Django :: 5.2
16
+ Classifier: Framework :: Django :: 6.0
17
+ Classifier: Framework :: Django :: 6.1
12
18
  Classifier: Intended Audience :: Developers
13
19
  Classifier: License :: OSI Approved :: MIT License
14
20
  Classifier: Operating System :: OS Independent
@@ -49,6 +55,7 @@ Explains Django exceptions on the debug page, pointing at the real fix in your o
49
55
  <p align="center">
50
56
  <a href="https://pypi.org/project/django-explain-errors/"><img src="https://img.shields.io/pypi/v/django-explain-errors" alt="PyPI version"></a>
51
57
  <a href="https://pypi.org/project/django-explain-errors/"><img src="https://img.shields.io/pypi/pyversions/django-explain-errors" alt="Python versions"></a>
58
+ <a href="https://pypi.org/project/django-explain-errors/"><img src="https://img.shields.io/pypi/djversions/django-explain-errors" alt="Django versions"></a>
52
59
  <a href="https://github.com/topunix/django-explain-errors/actions/workflows/test.yml"><img src="https://github.com/topunix/django-explain-errors/actions/workflows/test.yml/badge.svg?branch=main" alt="Tests"></a>
53
60
  <a href="https://github.com/topunix/django-explain-errors/blob/main/LICENSE"><img src="https://img.shields.io/pypi/l/django-explain-errors" alt="License"></a>
54
61
  </p>
@@ -539,41 +546,33 @@ django.db.utils.IntegrityError: NOT NULL constraint failed: blog_post.author_id
539
546
 
540
547
  ### Does RAG actually help?
541
548
 
542
- To check whether RAG-grounded explanations are actually better, not just
543
- longer, the package ships an eval harness (`evals/`): fifteen deliberately
544
- broken Django views, each explained twice (once from the traceback alone,
545
- once with RAG enabled) and judged by a separate model, blind to which
546
- explanation is which, against the error's known cause and correct fix
547
- location. Which side the judge sees as "A" is randomized per comparison so
548
- position can't bias the result.
549
-
550
- Across three runs (45 judged comparisons, 2 judge failures, 43 scored),
551
- RAG-on won 35, RAG-off 5, and 3 tied. The gap isn't spread evenly across
552
- everything the judge checks. It's concentrated in whether the explanation
553
- names the right file and function, and whether it invents details along
554
- the way: on `points_to_fix_location`, RAG-on answered yes in 26 of the
555
- group-A comparisons against RAG-off's 13; on `no_fabrication`, 26 against
556
- 17. Without source access, `gpt-4o-mini` tends to invent a
557
- plausible-sounding function name or parameter rather than say it doesn't
558
- know; given the actual code via RAG, it mostly does not.
559
-
560
- Three limitations are worth knowing before trusting this uncritically: RAG
561
- can anchor on the wrong retrieved chunk, as it did in one fixture
562
- (`missing_post_key`) where the fix got redirected to a retrieved template
563
- instead of the view; the judge is shown the failing function's own
564
- source, which is the same source RAG-on's retriever draws from, so part
565
- of RAG-on's `no_fabrication` advantage may be judge and generator
566
- overlapping on material RAG-off never sees rather than RAG-on being more
567
- careful; and claim statuses are spot-checked, not exhaustively audited --
568
- a script that flagged 14 of 363 claims on one run, all correct on manual
569
- inspection, is a sample that turned up no false positive, not a proof
570
- that none exists. Full per-fixture results, the judge prompt, and how to
571
- reproduce this (about $1.37 for a `--runs 3` pass, most of it judge cost)
572
- are in [`evals/README.md`](evals/README.md).
549
+ The package can explain an error in two ways:
550
+
551
+ - **RAG-off (default):** the model sees only the Django traceback.
552
+ - **RAG-on:** the model also sees relevant source code from your project, retrieved from a local index.
553
+
554
+ The eval harness in `evals/` tests whether RAG-on explanations are more accurate, not just longer. It triggers 15 deliberately broken Django views, explains each one both ways, and has a separate judge model compare the two against the error's known cause and fix location. The judge doesn't know which explanation used RAG, and their order is randomized.
555
+
556
+ **Results (3 runs, 43 scored comparisons):** RAG-on won 35, RAG-off won 5, and 3 tied.
557
+
558
+ Most of the gap comes from two checks, measured on the 10 fixtures whose cause is in the app's own code (30 comparisons):
559
+
560
+ - **Points to the right file and function:** RAG-on 26, RAG-off 13
561
+ - **Avoids invented details:** RAG-on 26, RAG-off 17
562
+
563
+ Without your source, gpt-4o-mini tends to invent a plausible function name or parameter rather than admit it doesn't know. With the real code in front of it, it mostly doesn't.
564
+
565
+ **Limitations:**
566
+
567
+ - RAG can retrieve the wrong code. In one fixture (`missing_post_key`), it pointed the fix at a template instead of the view.
568
+ - The judge checks claims against the same source RAG-on retrieves from, which may inflate RAG-on's score for avoiding invented details.
569
+ - Claims are spot-checked, not fully audited. All 14 claims flagged on one run held up on manual review, but that is a sample, not proof.
570
+
571
+ Full results, methodology, and how to reproduce (about $1.37 per `--runs 3` pass) are in [evals/README.md](https://github.com/topunix/django-explain-errors/blob/main/evals/README.md).
573
572
 
574
573
  ## License
575
574
 
576
- This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
575
+ This project is licensed under the MIT License. See the [LICENSE](https://github.com/topunix/django-explain-errors/blob/main/LICENSE) file for details.
577
576
 
578
577
  ## Contributing
579
578
 
@@ -10,7 +10,7 @@ with open('README.md', encoding='utf-8') as f:
10
10
 
11
11
  setup(
12
12
  name='django-explain-errors',
13
- version='0.9.1',
13
+ version='0.9.3',
14
14
  packages=find_packages(exclude=['tests', 'tests.*', 'evals', 'evals.*']),
15
15
  description='Django middleware that explains unhandled exceptions in DEBUG using an LLM, optionally grounded in your own project source via a local vector index. Works with OpenAI, Claude, or any OpenAI-compatible endpoint including local models.',
16
16
  long_description_content_type='text/markdown',
@@ -35,6 +35,12 @@ setup(
35
35
  'Development Status :: 4 - Beta',
36
36
  'Environment :: Web Environment',
37
37
  'Framework :: Django',
38
+ 'Framework :: Django :: 4.2',
39
+ 'Framework :: Django :: 5.0',
40
+ 'Framework :: Django :: 5.1',
41
+ 'Framework :: Django :: 5.2',
42
+ 'Framework :: Django :: 6.0',
43
+ 'Framework :: Django :: 6.1',
38
44
  'Intended Audience :: Developers',
39
45
  'License :: OSI Approved :: MIT License',
40
46
  'Operating System :: OS Independent',