contextgem 0.26.0__tar.gz → 0.27.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. {contextgem-0.26.0 → contextgem-0.27.0}/LICENSES.md +17 -15
  2. {contextgem-0.26.0 → contextgem-0.27.0}/PKG-INFO +5 -5
  3. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/__init__.py +1 -1
  4. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/base/documents.py +127 -0
  5. {contextgem-0.26.0 → contextgem-0.27.0}/pyproject.toml +5 -5
  6. {contextgem-0.26.0 → contextgem-0.27.0}/.gitignore +0 -0
  7. {contextgem-0.26.0 → contextgem-0.27.0}/LICENSE +0 -0
  8. {contextgem-0.26.0 → contextgem-0.27.0}/NOTICE +0 -0
  9. {contextgem-0.26.0 → contextgem-0.27.0}/README.md +0 -0
  10. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/__init__.py +0 -0
  11. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/base/__init__.py +0 -0
  12. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/base/abstract.py +0 -0
  13. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/base/aspects.py +0 -0
  14. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/base/attrs.py +0 -0
  15. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/base/concepts.py +0 -0
  16. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/base/data_models.py +0 -0
  17. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/base/examples.py +0 -0
  18. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/base/images.py +0 -0
  19. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/base/instances.py +0 -0
  20. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/base/items.py +0 -0
  21. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/base/llms.py +0 -0
  22. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/base/md_text.py +0 -0
  23. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/base/mixins.py +0 -0
  24. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/base/paras_and_sents.py +0 -0
  25. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/base/pipelines.py +0 -0
  26. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/base/serialization.py +0 -0
  27. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/base/utils.py +0 -0
  28. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/converters/__init__.py +0 -0
  29. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/converters/docx/__init__.py +0 -0
  30. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/converters/docx/base.py +0 -0
  31. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/converters/docx/namespaces.py +0 -0
  32. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/converters/docx/package.py +0 -0
  33. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/converters/docx/utils.py +0 -0
  34. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/data_models.py +0 -0
  35. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/decorators.py +0 -0
  36. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/exceptions.py +0 -0
  37. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/items.py +0 -0
  38. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/llm_output_structs/__init__.py +0 -0
  39. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/llm_output_structs/aspect_structs.py +0 -0
  40. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/llm_output_structs/concept_structs.py +0 -0
  41. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/llm_output_structs/utils.py +0 -0
  42. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/loggers.py +0 -0
  43. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/prompts/extract_aspect_items.j2 +0 -0
  44. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/prompts/extract_concept_items.j2 +0 -0
  45. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/registry.py +0 -0
  46. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/suppressions.py +0 -0
  47. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/system/default_system_message.j2 +0 -0
  48. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/tools/__init__.py +0 -0
  49. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/tools/docstring_parser.py +0 -0
  50. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/tools/schema_generator.py +0 -0
  51. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/typings/__init__.py +0 -0
  52. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/typings/strings_to_types.py +0 -0
  53. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/typings/typed_class_utils.py +0 -0
  54. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/typings/types.py +0 -0
  55. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/typings/types_normalization.py +0 -0
  56. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/typings/types_to_strings.py +0 -0
  57. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/typings/user_type_hints_validation.py +0 -0
  58. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/typings/validators.py +0 -0
  59. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/internal/utils.py +0 -0
  60. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/public/__init__.py +0 -0
  61. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/public/aspects.py +0 -0
  62. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/public/concepts.py +0 -0
  63. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/public/converters/__init__.py +0 -0
  64. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/public/converters/docx.py +0 -0
  65. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/public/data_models.py +0 -0
  66. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/public/decorators.py +0 -0
  67. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/public/documents.py +0 -0
  68. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/public/examples.py +0 -0
  69. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/public/images.py +0 -0
  70. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/public/llms.py +0 -0
  71. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/public/paragraphs.py +0 -0
  72. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/public/pipelines.py +0 -0
  73. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/public/sentences.py +0 -0
  74. {contextgem-0.26.0 → contextgem-0.27.0}/contextgem/public/utils.py +0 -0
@@ -9,44 +9,46 @@
9
9
  | └─ [colorama (0.4.6)](https://pypi.org/project/colorama/) (also: litellm, openai +1 more)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
10
10
  |[docstring-parser (0.18.0)](https://pypi.org/project/docstring-parser/)|python|prod|[pyproject.toml](pyproject.toml)|[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
11
11
  |[fastjsonschema (2.22.1)](https://pypi.org/project/fastjsonschema/)|python|prod|[pyproject.toml](pyproject.toml)|[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
12
- |[genai-prices (0.0.72)](https://pypi.org/project/genai-prices/)|python|prod|[pyproject.toml](pyproject.toml)|[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
12
+ |[genai-prices (0.1.2)](https://pypi.org/project/genai-prices/)|python|prod|[pyproject.toml](pyproject.toml)|[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
13
13
  | └─ [annotated-types (0.8.0)](https://pypi.org/project/annotated-types/) (also: litellm, openai +1 more)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
14
14
  | └─ [anyio (4.14.2)](https://pypi.org/project/anyio/) (also: litellm, openai +1 more)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
15
15
  | └─ [exceptiongroup (1.3.1)](https://pypi.org/project/exceptiongroup/) (also: litellm, openai +1 more)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
16
16
  | └─ [h11 (0.16.0)](https://pypi.org/project/h11/) (also: litellm, openai +1 more)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
17
- | └─ [httpcore2 (2.9.1)](https://pypi.org/project/httpcore2/)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
18
- | └─ [httpx2 (2.9.1)](https://pypi.org/project/httpx2/)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
17
+ | └─ [httpcore2 (2.10.0)](https://pypi.org/project/httpcore2/)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
18
+ | └─ [httpx2 (2.10.0)](https://pypi.org/project/httpx2/)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
19
+ | └─ [httpx2-jsfetch (1.0.0)](https://pypi.org/project/httpx2-jsfetch/)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
19
20
  | └─ [idna (3.18.0)](https://pypi.org/project/idna/) (also: litellm, openai +1 more)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
20
21
  | └─ [pydantic-core (2.46.4)](https://pypi.org/project/pydantic-core/) (also: litellm, openai +1 more)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
21
22
  | └─ [truststore (0.10.4)](https://pypi.org/project/truststore/)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
22
- | └─ [typing-inspection (0.4.2)](https://pypi.org/project/typing-inspection/) (also: litellm, openai +1 more)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
23
+ | └─ [typing-inspection (0.4.4)](https://pypi.org/project/typing-inspection/) (also: litellm, openai +1 more)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
23
24
  |[jinja2 (3.1.6)](https://pypi.org/project/jinja2/)|python|prod|[pyproject.toml](pyproject.toml)|[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
24
25
  | └─ [markupsafe (3.0.3)](https://pypi.org/project/markupsafe/) (also: litellm)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
25
- |[litellm (1.93.0)](https://pypi.org/project/litellm/)|python|prod|[pyproject.toml](pyproject.toml)|[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
26
+ |[litellm (1.96.2)](https://pypi.org/project/litellm/)|python|prod|[pyproject.toml](pyproject.toml)|[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
26
27
  | └─ [aiohappyeyeballs (2.7.1)](https://pypi.org/project/aiohappyeyeballs/)|python|prod||[PSF-2.0](https://spdx.org/licenses/PSF-2.0.html)|permissive|✓|
27
28
  | └─ [aiohttp (3.14.3)](https://pypi.org/project/aiohttp/)|python|prod||[Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) AND [MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
28
29
  | └─ [aiosignal (1.4.0)](https://pypi.org/project/aiosignal/)|python|prod||[Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)|permissive|✓|
29
30
  | └─ [async-timeout (5.0.1)](https://pypi.org/project/async-timeout/)|python|prod||[Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)|permissive|✓|
30
31
  | └─ [attrs (26.1.0)](https://pypi.org/project/attrs/)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
31
32
  | └─ [certifi (2026.7.22)](https://pypi.org/project/certifi/) (also: openai, wtpsplit-lite)|python|prod||[MPL-2.0](https://spdx.org/licenses/MPL-2.0.html)|weak-copyleft|⚠|
32
- | └─ [charset-normalizer (3.4.9)](https://pypi.org/project/charset-normalizer/)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
33
+ | └─ [charset-normalizer (3.5.0)](https://pypi.org/project/charset-normalizer/)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
33
34
  | └─ [click (8.4.2)](https://pypi.org/project/click/) (also: wtpsplit-lite)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
34
35
  | └─ [distro (1.9.0)](https://pypi.org/project/distro/) (also: openai)|python|prod||[Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)|permissive|✓|
35
36
  | └─ [fastuuid (0.14.0)](https://pypi.org/project/fastuuid/)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
36
- | └─ [filelock (3.32.0)](https://pypi.org/project/filelock/) (also: wtpsplit-lite)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
37
+ | └─ [filelock (3.32.2)](https://pypi.org/project/filelock/) (also: wtpsplit-lite)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
37
38
  | └─ [frozenlist (1.8.0)](https://pypi.org/project/frozenlist/)|python|prod||[Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)|permissive|✓|
38
39
  | └─ [fsspec (2026.7.0)](https://pypi.org/project/fsspec/) (also: wtpsplit-lite)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
39
- | └─ [hf-xet (1.5.2)](https://pypi.org/project/hf-xet/) (also: wtpsplit-lite)|python|prod||[Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)|permissive|✓|
40
+ | └─ [hf-xet (1.6.0)](https://pypi.org/project/hf-xet/) (also: wtpsplit-lite)|python|prod||[Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)|permissive|✓|
40
41
  | └─ [httpcore (1.0.9)](https://pypi.org/project/httpcore/) (also: openai, wtpsplit-lite)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
41
42
  | └─ [httpx (0.28.1)](https://pypi.org/project/httpx/) (also: openai, wtpsplit-lite)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
42
- | └─ [huggingface-hub (1.25.1)](https://pypi.org/project/huggingface-hub/) (also: wtpsplit-lite)|python|prod||[Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)|permissive|✓|
43
+ | └─ [huggingface-hub (1.27.0)](https://pypi.org/project/huggingface-hub/) (also: wtpsplit-lite)|python|prod||[Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)|permissive|✓|
43
44
  | └─ [importlib-metadata (8.9.0)](https://pypi.org/project/importlib-metadata/)|python|prod||[Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)|permissive|✓|
44
45
  | └─ [jiter (0.16.0)](https://pypi.org/project/jiter/) (also: openai)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
45
46
  | └─ [jsonschema (4.26.0)](https://pypi.org/project/jsonschema/)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
46
47
  | └─ [jsonschema-specifications (2025.9.1)](https://pypi.org/project/jsonschema-specifications/)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
47
48
  | └─ [multidict (6.7.1)](https://pypi.org/project/multidict/)|python|prod||[Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)|permissive|✓|
48
- | └─ [packaging (26.2.0)](https://pypi.org/project/packaging/) (also: onnxruntime, wtpsplit-lite)|python|prod||[Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) OR [BSD-2-Clause](https://spdx.org/licenses/BSD-2-Clause.html)|permissive|✓|
49
+ | └─ [packaging (26.3.0)](https://pypi.org/project/packaging/) (also: onnxruntime, wtpsplit-lite)|python|prod||[Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) OR [BSD-2-Clause](https://spdx.org/licenses/BSD-2-Clause.html)|permissive|✓|
49
50
  | └─ [propcache (0.5.2)](https://pypi.org/project/propcache/)|python|prod||[Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)|permissive|✓|
51
+ | └─ [pydantic-settings (2.15.0)](https://pypi.org/project/pydantic-settings/)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
50
52
  | └─ [pyyaml (6.0.3)](https://pypi.org/project/pyyaml/) (also: wtpsplit-lite)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
51
53
  | └─ [referencing (0.37.0)](https://pypi.org/project/referencing/)|python|prod||[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
52
54
  | └─ [regex (2026.7.19)](https://pypi.org/project/regex/)|python|prod||[Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) AND [CNRI-Python](https://spdx.org/licenses/CNRI-Python.html)|unknown|?|
@@ -68,7 +70,7 @@
68
70
  | └─ [mpmath (1.3.0)](https://pypi.org/project/mpmath/) (also: wtpsplit-lite)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
69
71
  | └─ [numpy (2.2.6)](https://pypi.org/project/numpy/) (also: wtpsplit-lite)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
70
72
  | └─ [numpy (2.4.6)](https://pypi.org/project/numpy/) (also: wtpsplit-lite)|python|prod||[0BSD](https://spdx.org/licenses/0BSD.html) AND [BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html) AND [CC0-1.0](https://spdx.org/licenses/CC0-1.0.html) AND [MIT](https://spdx.org/licenses/MIT.html) AND [Zlib](https://spdx.org/licenses/Zlib.html)|permissive|✓|
71
- | └─ [numpy (2.5.1)](https://pypi.org/project/numpy/) (also: wtpsplit-lite)|python|prod||[0BSD](https://spdx.org/licenses/0BSD.html) AND [BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html) AND [CC0-1.0](https://spdx.org/licenses/CC0-1.0.html) AND [MIT](https://spdx.org/licenses/MIT.html) AND [Zlib](https://spdx.org/licenses/Zlib.html)|permissive|✓|
73
+ | └─ [numpy (2.5.2)](https://pypi.org/project/numpy/) (also: wtpsplit-lite)|python|prod||[0BSD](https://spdx.org/licenses/0BSD.html) AND [BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html) AND [CC0-1.0](https://spdx.org/licenses/CC0-1.0.html) AND [MIT](https://spdx.org/licenses/MIT.html) AND [Zlib](https://spdx.org/licenses/Zlib.html)|permissive|✓|
72
74
  | └─ [protobuf (7.35.1)](https://pypi.org/project/protobuf/) (also: wtpsplit-lite)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
73
75
  | └─ [pyreadline3 (3.5.6)](https://pypi.org/project/pyreadline3/) (also: wtpsplit-lite)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
74
76
  | └─ [sympy (1.14.0)](https://pypi.org/project/sympy/) (also: wtpsplit-lite)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
@@ -79,11 +81,11 @@
79
81
  | └─ [mpmath (1.3.0)](https://pypi.org/project/mpmath/) (also: wtpsplit-lite)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
80
82
  | └─ [numpy (2.2.6)](https://pypi.org/project/numpy/) (also: wtpsplit-lite)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
81
83
  | └─ [numpy (2.4.6)](https://pypi.org/project/numpy/) (also: wtpsplit-lite)|python|prod||[0BSD](https://spdx.org/licenses/0BSD.html) AND [BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html) AND [CC0-1.0](https://spdx.org/licenses/CC0-1.0.html) AND [MIT](https://spdx.org/licenses/MIT.html) AND [Zlib](https://spdx.org/licenses/Zlib.html)|permissive|✓|
82
- | └─ [numpy (2.5.1)](https://pypi.org/project/numpy/) (also: wtpsplit-lite)|python|prod||[0BSD](https://spdx.org/licenses/0BSD.html) AND [BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html) AND [CC0-1.0](https://spdx.org/licenses/CC0-1.0.html) AND [MIT](https://spdx.org/licenses/MIT.html) AND [Zlib](https://spdx.org/licenses/Zlib.html)|permissive|✓|
84
+ | └─ [numpy (2.5.2)](https://pypi.org/project/numpy/) (also: wtpsplit-lite)|python|prod||[0BSD](https://spdx.org/licenses/0BSD.html) AND [BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html) AND [CC0-1.0](https://spdx.org/licenses/CC0-1.0.html) AND [MIT](https://spdx.org/licenses/MIT.html) AND [Zlib](https://spdx.org/licenses/Zlib.html)|permissive|✓|
83
85
  | └─ [protobuf (7.35.1)](https://pypi.org/project/protobuf/) (also: wtpsplit-lite)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
84
86
  | └─ [pyreadline3 (3.5.6)](https://pypi.org/project/pyreadline3/) (also: wtpsplit-lite)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
85
87
  | └─ [sympy (1.14.0)](https://pypi.org/project/sympy/) (also: wtpsplit-lite)|python|prod||[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
86
- |[openai (2.49.0)](https://pypi.org/project/openai/)|python|prod|[pyproject.toml](pyproject.toml)|[Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)|permissive|✓|
88
+ |[openai (2.54.0)](https://pypi.org/project/openai/)|python|prod|[pyproject.toml](pyproject.toml)|[Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)|permissive|✓|
87
89
  |[pillow (11.3.0)](https://pypi.org/project/pillow/)|python|prod|[pyproject.toml](pyproject.toml)|[MIT-CMU](https://spdx.org/licenses/MIT-CMU.html)|permissive|✓|
88
90
  |[pydantic (2.13.4)](https://pypi.org/project/pydantic/)|python|prod|[pyproject.toml](pyproject.toml)|[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
89
91
  |[python-dotenv (1.2.2)](https://pypi.org/project/python-dotenv/)|python|prod|[pyproject.toml](pyproject.toml)|[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)|permissive|✓|
@@ -93,9 +95,9 @@
93
95
  |[typing-extensions (4.16.0)](https://pypi.org/project/typing-extensions/)|python|prod|[pyproject.toml](pyproject.toml)|[PSF-2.0](https://spdx.org/licenses/PSF-2.0.html)|permissive|✓|
94
96
  |[wtpsplit-lite (0.2.0)](https://pypi.org/project/wtpsplit-lite/)|python|prod|[pyproject.toml](pyproject.toml)|[MIT](https://spdx.org/licenses/MIT.html)|permissive|✓|
95
97
 
96
- **Summary:** 0 violations, 2 warnings, 1 unknown, 75 ok (of which 4 reviewed)
98
+ **Summary:** 0 violations, 2 warnings, 1 unknown, 77 ok (of which 4 reviewed)
97
99
 
98
- **Completed in:** 0.66s
100
+ **Completed in:** 0.61s
99
101
 
100
102
  ## Details
101
103
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: contextgem
3
- Version: 0.26.0
3
+ Version: 0.27.0
4
4
  Summary: Effortless LLM extraction from documents
5
5
  Project-URL: Homepage, https://github.com/shcherbak-ai/contextgem
6
6
  Project-URL: Documentation, https://github.com/shcherbak-ai/contextgem/blob/main/README.md
@@ -42,13 +42,13 @@ Requires-Dist: aiolimiter<2.0.0,>=1.2.1
42
42
  Requires-Dist: colorlog<7.0.0,>=6.9.0
43
43
  Requires-Dist: docstring-parser<1.0.0,>=0.17.0
44
44
  Requires-Dist: fastjsonschema<3.0.0,>=2.21.2
45
- Requires-Dist: genai-prices==0.0.72
45
+ Requires-Dist: genai-prices==0.1.2
46
46
  Requires-Dist: jinja2<4.0.0,>=3.1.5
47
- Requires-Dist: litellm==1.93.0
47
+ Requires-Dist: litellm==1.96.2
48
48
  Requires-Dist: lxml<7.0.0,>=5.4.0
49
49
  Requires-Dist: onnxruntime<1.24.0; python_version < '3.11'
50
50
  Requires-Dist: onnxruntime>=1.24.0; python_version >= '3.14'
51
- Requires-Dist: openai==2.49.0
51
+ Requires-Dist: openai==2.54.0
52
52
  Requires-Dist: pillow<12.0.0,>=11.3.0
53
53
  Requires-Dist: pydantic<3.0.0,>=2.10.6
54
54
  Requires-Dist: python-ulid<4.0.0,>=3.0.0
@@ -20,7 +20,7 @@
20
20
  ContextGem - Effortless LLM extraction from documents
21
21
  """
22
22
 
23
- __version__ = "0.26.0"
23
+ __version__ = "0.27.0"
24
24
  __author__ = "Shcherbak AI AS"
25
25
 
26
26
  from contextgem.public import (
@@ -62,6 +62,17 @@ from contextgem.internal.utils import (
62
62
  )
63
63
 
64
64
 
65
+ # Instance-dict keys for the lazily built paragraph/sentence position lookup caches.
66
+ # Deliberately stored as plain instance-dict entries rather than model fields or
67
+ # private attributes: pydantic ignores non-field `__dict__` entries in model
68
+ # equality (see pydantic GH-7444), and `to_dict()` serializes only fields and
69
+ # allowlisted private attributes, so the caches never affect document equality,
70
+ # serialization, or cloning.
71
+ _PARA_POS_CACHE_KEY = "_para_index_map"
72
+ _SENT_POS_CACHE_KEY = "_sent_index_map"
73
+ _POSITION_CACHE_KEYS = (_PARA_POS_CACHE_KEY, _SENT_POS_CACHE_KEY)
74
+
75
+
65
76
  @_disable_direct_initialization
66
77
  class _Document(_AssignedInstancesProcessor, _MarkdownTextAttributesProcessor):
67
78
  """
@@ -155,6 +166,122 @@ class _Document(_AssignedInstancesProcessor, _MarkdownTextAttributesProcessor):
155
166
  """
156
167
  return list(itertools.chain.from_iterable(i.sentences for i in self.paragraphs))
157
168
 
169
+ def get_paragraph_index(self, paragraph: _Paragraph) -> int:
170
+ """
171
+ Returns the 0-based position of a paragraph in the document's ``paragraphs`` list.
172
+
173
+ Lookup is keyed by the paragraph's unique ID rather than text equality, so
174
+ paragraphs with identical text (e.g. duplicate clauses in a contract) resolve
175
+ to their specific occurrences. This makes the method suitable for locating
176
+ reference paragraphs (``reference_paragraphs``) returned during extraction.
177
+ Unique IDs are preserved by serialization, so lookups also work across
178
+ ``to_dict()``/``from_dict()`` round-trips.
179
+
180
+ Lookups are O(1) on average via a lazily built cache. The cache is an
181
+ internal implementation detail: it is validated against the live
182
+ document state on each hit, rebuilt when stale, and does not affect
183
+ document equality, serialization, or cloning.
184
+
185
+ :param paragraph: The paragraph to locate. Must be a paragraph object that
186
+ belongs to this document, e.g. accessed via ``document.paragraphs`` or
187
+ extraction references.
188
+ :type paragraph: _Paragraph
189
+ :return: 0-based index of the paragraph in ``document.paragraphs``.
190
+ :rtype: int
191
+ :raises ValueError: If the paragraph is not found in the document's paragraphs.
192
+ """
193
+ uid = paragraph.unique_id
194
+ index_map: dict[str, int] | None = self.__dict__.get(_PARA_POS_CACHE_KEY)
195
+ idx = index_map.get(uid) if index_map is not None else None
196
+ # Verify the cached entry against the live list, so that lookups never
197
+ # return stale positions (e.g. after unsupported in-place list mutations)
198
+ if idx is not None and not (
199
+ idx < len(self.paragraphs) and self.paragraphs[idx].unique_id == uid
200
+ ):
201
+ idx = None
202
+ if idx is None:
203
+ # Lazily (re)build the cache, e.g. on first use, after paragraphs
204
+ # have been populated, or when a cached entry went stale
205
+ index_map = {p.unique_id: i for i, p in enumerate(self.paragraphs)}
206
+ self.__dict__[_PARA_POS_CACHE_KEY] = index_map
207
+ idx = index_map.get(uid)
208
+ if idx is None:
209
+ raise ValueError(
210
+ "Paragraph was not found in the document's paragraphs. "
211
+ "Position lookup requires a paragraph object that belongs to this "
212
+ "document, e.g. one accessed via `document.paragraphs` or "
213
+ "extraction references."
214
+ )
215
+ return idx
216
+
217
+ def get_sentence_index(self, sentence: _Sentence) -> tuple[int, int]:
218
+ """
219
+ Returns the position of a sentence in the document as a
220
+ ``(paragraph_index, sentence_index)`` tuple, where ``paragraph_index`` is
221
+ the 0-based position of the sentence's paragraph in ``document.paragraphs``
222
+ and ``sentence_index`` is the 0-based position of the sentence within that
223
+ paragraph's ``sentences`` list.
224
+
225
+ Lookup is keyed by the sentence's unique ID rather than text equality, so
226
+ sentences with identical text resolve to their specific occurrences. This
227
+ makes the method suitable for locating reference sentences
228
+ (``reference_sentences``) returned during extraction. Unique IDs are
229
+ preserved by serialization, so lookups also work across
230
+ ``to_dict()``/``from_dict()`` round-trips. The returned tuples sort in
231
+ document order.
232
+
233
+ Lookups are O(1) on average via a lazily built cache. The cache is an
234
+ internal implementation detail: it is validated against the live
235
+ document state on each hit, rebuilt when stale, and does not affect
236
+ document equality, serialization, or cloning.
237
+
238
+ :param sentence: The sentence to locate. Must be a sentence object that
239
+ belongs to this document's paragraphs, e.g. accessed via
240
+ ``paragraph.sentences`` or extraction references.
241
+ :type sentence: _Sentence
242
+ :return: ``(paragraph_index, sentence_index)`` position of the sentence.
243
+ :rtype: tuple[int, int]
244
+ :raises ValueError: If the sentence is not found in the document's paragraphs.
245
+ """
246
+ uid = sentence.unique_id
247
+ index_map: dict[str, tuple[int, int]] | None = self.__dict__.get(
248
+ _SENT_POS_CACHE_KEY
249
+ )
250
+ pos = index_map.get(uid) if index_map is not None else None
251
+ # Verify the cached entry against the live lists, so that lookups never
252
+ # return stale positions (e.g. after unsupported in-place list mutations)
253
+ if pos is not None:
254
+ para_idx, sent_idx = pos
255
+ if not (
256
+ para_idx < len(self.paragraphs)
257
+ and sent_idx < len(self.paragraphs[para_idx].sentences)
258
+ and self.paragraphs[para_idx].sentences[sent_idx].unique_id == uid
259
+ ):
260
+ pos = None
261
+ if pos is None:
262
+ # Lazily (re)build the cache, e.g. on first use, after sentences
263
+ # have been segmented, or when a cached entry went stale
264
+ index_map = {
265
+ s.unique_id: (para_idx, sent_idx)
266
+ for para_idx, p in enumerate(self.paragraphs)
267
+ for sent_idx, s in enumerate(p.sentences)
268
+ }
269
+ self.__dict__[_SENT_POS_CACHE_KEY] = index_map
270
+ pos = index_map.get(uid)
271
+ if pos is None:
272
+ hint = (
273
+ " Note that the document's paragraphs have no sentences segmented yet."
274
+ if not any(p.sentences for p in self.paragraphs)
275
+ else ""
276
+ )
277
+ raise ValueError(
278
+ "Sentence was not found in the document's paragraphs. "
279
+ "Position lookup requires a sentence object that belongs to this "
280
+ "document, e.g. one accessed via `paragraph.sentences` or "
281
+ f"extraction references.{hint}"
282
+ )
283
+ return pos
284
+
158
285
  @_timer_decorator(
159
286
  "Document initialization",
160
287
  )
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "contextgem"
3
- version = "0.26.0"
3
+ version = "0.27.0"
4
4
  description = "Effortless LLM extraction from documents"
5
5
  authors = [{ name = "shcherbak-ai", email = "sergii@shcherbak.ai" }]
6
6
  requires-python = ">=3.10,<3.15"
@@ -96,11 +96,11 @@ dependencies = [
96
96
  "colorlog (>=6.9.0,<7.0.0)",
97
97
  "docstring-parser (>=0.17.0,<1.0.0)",
98
98
  "fastjsonschema (>=2.21.2,<3.0.0)",
99
- "genai-prices==0.0.72", # pin version due to frequent API changes
99
+ "genai-prices==0.1.2", # pin version due to frequent API changes
100
100
  "jinja2 (>=3.1.5,<4.0.0)",
101
- "litellm==1.93.0", # pin version due to occasional instability between patches and minor versions
101
+ "litellm==1.96.2", # pin version due to occasional instability between patches and minor versions
102
102
  "lxml (>=5.4.0,<7.0.0)",
103
- "openai==2.49.0", # pinned version for stable compatibility with litellm (after issue with 1.100.0)
103
+ "openai==2.54.0", # pinned version for stable compatibility with litellm (after issue with 1.100.0)
104
104
  "pillow (>=11.3.0,<12.0.0)",
105
105
  "pydantic (>=2.10.6,<3.0.0)",
106
106
  "python-ulid (>=3.0.0,<4.0.0)",
@@ -212,7 +212,7 @@ log_cli_level = "WARNING"
212
212
 
213
213
  [tool.commitizen]
214
214
  name = "cz_conventional_commits"
215
- version = "0.26.0"
215
+ version = "0.27.0"
216
216
  version_files = [
217
217
  "contextgem/__init__.py:__version__",
218
218
  "pyproject.toml:version",
File without changes
File without changes
File without changes
File without changes