koichi12 commited on
Commit
23aa6b4
·
verified ·
1 Parent(s): 2e5a844

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .venv/lib/python3.11/site-packages/distro/__init__.py +54 -0
  2. .venv/lib/python3.11/site-packages/distro/__main__.py +4 -0
  3. .venv/lib/python3.11/site-packages/distro/__pycache__/__init__.cpython-311.pyc +0 -0
  4. .venv/lib/python3.11/site-packages/distro/__pycache__/__main__.cpython-311.pyc +0 -0
  5. .venv/lib/python3.11/site-packages/distro/__pycache__/distro.cpython-311.pyc +0 -0
  6. .venv/lib/python3.11/site-packages/distro/distro.py +1403 -0
  7. .venv/lib/python3.11/site-packages/distro/py.typed +0 -0
  8. .venv/lib/python3.11/site-packages/gguf-0.10.0.dist-info/INSTALLER +1 -0
  9. .venv/lib/python3.11/site-packages/gguf-0.10.0.dist-info/LICENSE +21 -0
  10. .venv/lib/python3.11/site-packages/gguf-0.10.0.dist-info/METADATA +114 -0
  11. .venv/lib/python3.11/site-packages/gguf-0.10.0.dist-info/RECORD +45 -0
  12. .venv/lib/python3.11/site-packages/gguf-0.10.0.dist-info/WHEEL +4 -0
  13. .venv/lib/python3.11/site-packages/gguf-0.10.0.dist-info/entry_points.txt +6 -0
  14. .venv/lib/python3.11/site-packages/mistral_common/__init__.py +1 -0
  15. .venv/lib/python3.11/site-packages/mistral_common/base.py +9 -0
  16. .venv/lib/python3.11/site-packages/mistral_common/exceptions.py +67 -0
  17. .venv/lib/python3.11/site-packages/mistral_common/multimodal.py +70 -0
  18. .venv/lib/python3.11/site-packages/mistral_common/protocol/__init__.py +0 -0
  19. .venv/lib/python3.11/site-packages/mistral_common/protocol/__pycache__/__init__.cpython-311.pyc +0 -0
  20. .venv/lib/python3.11/site-packages/mistral_common/protocol/__pycache__/base.cpython-311.pyc +0 -0
  21. .venv/lib/python3.11/site-packages/mistral_common/protocol/__pycache__/utils.cpython-311.pyc +0 -0
  22. .venv/lib/python3.11/site-packages/mistral_common/protocol/base.py +18 -0
  23. .venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/__init__.py +0 -0
  24. .venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/__pycache__/normalize.cpython-311.pyc +0 -0
  25. .venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/__pycache__/request.cpython-311.pyc +0 -0
  26. .venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/__pycache__/tool_calls.cpython-311.pyc +0 -0
  27. .venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/__pycache__/validator.cpython-311.pyc +0 -0
  28. .venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/messages.py +113 -0
  29. .venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/normalize.py +265 -0
  30. .venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/request.py +27 -0
  31. .venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/response.py +66 -0
  32. .venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/tool_calls.py +51 -0
  33. .venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/validator.py +328 -0
  34. .venv/lib/python3.11/site-packages/mistral_common/protocol/utils.py +5 -0
  35. .venv/lib/python3.11/site-packages/mistral_common/py.typed +0 -0
  36. .venv/lib/python3.11/site-packages/numpy/polynomial/tests/__pycache__/__init__.cpython-311.pyc +0 -0
  37. .venv/lib/python3.11/site-packages/numpy/polynomial/tests/__pycache__/test_hermite_e.cpython-311.pyc +0 -0
  38. .venv/lib/python3.11/site-packages/vllm-0.7.2.dist-info/INSTALLER +1 -0
  39. .venv/lib/python3.11/site-packages/vllm-0.7.2.dist-info/LICENSE +201 -0
  40. .venv/lib/python3.11/site-packages/vllm-0.7.2.dist-info/METADATA +238 -0
  41. .venv/lib/python3.11/site-packages/vllm-0.7.2.dist-info/RECORD +0 -0
  42. .venv/lib/python3.11/site-packages/vllm-0.7.2.dist-info/REQUESTED +0 -0
  43. .venv/lib/python3.11/site-packages/vllm-0.7.2.dist-info/WHEEL +5 -0
  44. .venv/lib/python3.11/site-packages/vllm-0.7.2.dist-info/entry_points.txt +2 -0
  45. .venv/lib/python3.11/site-packages/vllm-0.7.2.dist-info/top_level.txt +1 -0
  46. .venv/lib/python3.11/site-packages/xgrammar/__init__.py +13 -0
  47. .venv/lib/python3.11/site-packages/xgrammar/__pycache__/__init__.cpython-311.pyc +0 -0
  48. .venv/lib/python3.11/site-packages/xgrammar/__pycache__/base.cpython-311.pyc +0 -0
  49. .venv/lib/python3.11/site-packages/xgrammar/__pycache__/compiler.cpython-311.pyc +0 -0
  50. .venv/lib/python3.11/site-packages/xgrammar/__pycache__/grammar.cpython-311.pyc +0 -0
.venv/lib/python3.11/site-packages/distro/__init__.py ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .distro import (
2
+ NORMALIZED_DISTRO_ID,
3
+ NORMALIZED_LSB_ID,
4
+ NORMALIZED_OS_ID,
5
+ LinuxDistribution,
6
+ __version__,
7
+ build_number,
8
+ codename,
9
+ distro_release_attr,
10
+ distro_release_info,
11
+ id,
12
+ info,
13
+ like,
14
+ linux_distribution,
15
+ lsb_release_attr,
16
+ lsb_release_info,
17
+ major_version,
18
+ minor_version,
19
+ name,
20
+ os_release_attr,
21
+ os_release_info,
22
+ uname_attr,
23
+ uname_info,
24
+ version,
25
+ version_parts,
26
+ )
27
+
28
+ __all__ = [
29
+ "NORMALIZED_DISTRO_ID",
30
+ "NORMALIZED_LSB_ID",
31
+ "NORMALIZED_OS_ID",
32
+ "LinuxDistribution",
33
+ "build_number",
34
+ "codename",
35
+ "distro_release_attr",
36
+ "distro_release_info",
37
+ "id",
38
+ "info",
39
+ "like",
40
+ "linux_distribution",
41
+ "lsb_release_attr",
42
+ "lsb_release_info",
43
+ "major_version",
44
+ "minor_version",
45
+ "name",
46
+ "os_release_attr",
47
+ "os_release_info",
48
+ "uname_attr",
49
+ "uname_info",
50
+ "version",
51
+ "version_parts",
52
+ ]
53
+
54
+ __version__ = __version__
.venv/lib/python3.11/site-packages/distro/__main__.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ from .distro import main
2
+
3
+ if __name__ == "__main__":
4
+ main()
.venv/lib/python3.11/site-packages/distro/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (1.18 kB). View file
 
.venv/lib/python3.11/site-packages/distro/__pycache__/__main__.cpython-311.pyc ADDED
Binary file (312 Bytes). View file
 
.venv/lib/python3.11/site-packages/distro/__pycache__/distro.cpython-311.pyc ADDED
Binary file (57.8 kB). View file
 
.venv/lib/python3.11/site-packages/distro/distro.py ADDED
@@ -0,0 +1,1403 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ # Copyright 2015-2021 Nir Cohen
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ """
17
+ The ``distro`` package (``distro`` stands for Linux Distribution) provides
18
+ information about the Linux distribution it runs on, such as a reliable
19
+ machine-readable distro ID, or version information.
20
+
21
+ It is the recommended replacement for Python's original
22
+ :py:func:`platform.linux_distribution` function, but it provides much more
23
+ functionality. An alternative implementation became necessary because Python
24
+ 3.5 deprecated this function, and Python 3.8 removed it altogether. Its
25
+ predecessor function :py:func:`platform.dist` was already deprecated since
26
+ Python 2.6 and removed in Python 3.8. Still, there are many cases in which
27
+ access to OS distribution information is needed. See `Python issue 1322
28
+ <https://bugs.python.org/issue1322>`_ for more information.
29
+ """
30
+
31
+ import argparse
32
+ import json
33
+ import logging
34
+ import os
35
+ import re
36
+ import shlex
37
+ import subprocess
38
+ import sys
39
+ import warnings
40
+ from typing import (
41
+ Any,
42
+ Callable,
43
+ Dict,
44
+ Iterable,
45
+ Optional,
46
+ Sequence,
47
+ TextIO,
48
+ Tuple,
49
+ Type,
50
+ )
51
+
52
+ try:
53
+ from typing import TypedDict
54
+ except ImportError:
55
+ # Python 3.7
56
+ TypedDict = dict
57
+
58
+ __version__ = "1.9.0"
59
+
60
+
61
+ class VersionDict(TypedDict):
62
+ major: str
63
+ minor: str
64
+ build_number: str
65
+
66
+
67
+ class InfoDict(TypedDict):
68
+ id: str
69
+ version: str
70
+ version_parts: VersionDict
71
+ like: str
72
+ codename: str
73
+
74
+
75
+ _UNIXCONFDIR = os.environ.get("UNIXCONFDIR", "/etc")
76
+ _UNIXUSRLIBDIR = os.environ.get("UNIXUSRLIBDIR", "/usr/lib")
77
+ _OS_RELEASE_BASENAME = "os-release"
78
+
79
+ #: Translation table for normalizing the "ID" attribute defined in os-release
80
+ #: files, for use by the :func:`distro.id` method.
81
+ #:
82
+ #: * Key: Value as defined in the os-release file, translated to lower case,
83
+ #: with blanks translated to underscores.
84
+ #:
85
+ #: * Value: Normalized value.
86
+ NORMALIZED_OS_ID = {
87
+ "ol": "oracle", # Oracle Linux
88
+ "opensuse-leap": "opensuse", # Newer versions of OpenSuSE report as opensuse-leap
89
+ }
90
+
91
+ #: Translation table for normalizing the "Distributor ID" attribute returned by
92
+ #: the lsb_release command, for use by the :func:`distro.id` method.
93
+ #:
94
+ #: * Key: Value as returned by the lsb_release command, translated to lower
95
+ #: case, with blanks translated to underscores.
96
+ #:
97
+ #: * Value: Normalized value.
98
+ NORMALIZED_LSB_ID = {
99
+ "enterpriseenterpriseas": "oracle", # Oracle Enterprise Linux 4
100
+ "enterpriseenterpriseserver": "oracle", # Oracle Linux 5
101
+ "redhatenterpriseworkstation": "rhel", # RHEL 6, 7 Workstation
102
+ "redhatenterpriseserver": "rhel", # RHEL 6, 7 Server
103
+ "redhatenterprisecomputenode": "rhel", # RHEL 6 ComputeNode
104
+ }
105
+
106
+ #: Translation table for normalizing the distro ID derived from the file name
107
+ #: of distro release files, for use by the :func:`distro.id` method.
108
+ #:
109
+ #: * Key: Value as derived from the file name of a distro release file,
110
+ #: translated to lower case, with blanks translated to underscores.
111
+ #:
112
+ #: * Value: Normalized value.
113
+ NORMALIZED_DISTRO_ID = {
114
+ "redhat": "rhel", # RHEL 6.x, 7.x
115
+ }
116
+
117
+ # Pattern for content of distro release file (reversed)
118
+ _DISTRO_RELEASE_CONTENT_REVERSED_PATTERN = re.compile(
119
+ r"(?:[^)]*\)(.*)\()? *(?:STL )?([\d.+\-a-z]*\d) *(?:esaeler *)?(.+)"
120
+ )
121
+
122
+ # Pattern for base file name of distro release file
123
+ _DISTRO_RELEASE_BASENAME_PATTERN = re.compile(r"(\w+)[-_](release|version)$")
124
+
125
+ # Base file names to be looked up for if _UNIXCONFDIR is not readable.
126
+ _DISTRO_RELEASE_BASENAMES = [
127
+ "SuSE-release",
128
+ "altlinux-release",
129
+ "arch-release",
130
+ "base-release",
131
+ "centos-release",
132
+ "fedora-release",
133
+ "gentoo-release",
134
+ "mageia-release",
135
+ "mandrake-release",
136
+ "mandriva-release",
137
+ "mandrivalinux-release",
138
+ "manjaro-release",
139
+ "oracle-release",
140
+ "redhat-release",
141
+ "rocky-release",
142
+ "sl-release",
143
+ "slackware-version",
144
+ ]
145
+
146
+ # Base file names to be ignored when searching for distro release file
147
+ _DISTRO_RELEASE_IGNORE_BASENAMES = (
148
+ "debian_version",
149
+ "lsb-release",
150
+ "oem-release",
151
+ _OS_RELEASE_BASENAME,
152
+ "system-release",
153
+ "plesk-release",
154
+ "iredmail-release",
155
+ "board-release",
156
+ "ec2_version",
157
+ )
158
+
159
+
160
+ def linux_distribution(full_distribution_name: bool = True) -> Tuple[str, str, str]:
161
+ """
162
+ .. deprecated:: 1.6.0
163
+
164
+ :func:`distro.linux_distribution()` is deprecated. It should only be
165
+ used as a compatibility shim with Python's
166
+ :py:func:`platform.linux_distribution()`. Please use :func:`distro.id`,
167
+ :func:`distro.version` and :func:`distro.name` instead.
168
+
169
+ Return information about the current OS distribution as a tuple
170
+ ``(id_name, version, codename)`` with items as follows:
171
+
172
+ * ``id_name``: If *full_distribution_name* is false, the result of
173
+ :func:`distro.id`. Otherwise, the result of :func:`distro.name`.
174
+
175
+ * ``version``: The result of :func:`distro.version`.
176
+
177
+ * ``codename``: The extra item (usually in parentheses) after the
178
+ os-release version number, or the result of :func:`distro.codename`.
179
+
180
+ The interface of this function is compatible with the original
181
+ :py:func:`platform.linux_distribution` function, supporting a subset of
182
+ its parameters.
183
+
184
+ The data it returns may not exactly be the same, because it uses more data
185
+ sources than the original function, and that may lead to different data if
186
+ the OS distribution is not consistent across multiple data sources it
187
+ provides (there are indeed such distributions ...).
188
+
189
+ Another reason for differences is the fact that the :func:`distro.id`
190
+ method normalizes the distro ID string to a reliable machine-readable value
191
+ for a number of popular OS distributions.
192
+ """
193
+ warnings.warn(
194
+ "distro.linux_distribution() is deprecated. It should only be used as a "
195
+ "compatibility shim with Python's platform.linux_distribution(). Please use "
196
+ "distro.id(), distro.version() and distro.name() instead.",
197
+ DeprecationWarning,
198
+ stacklevel=2,
199
+ )
200
+ return _distro.linux_distribution(full_distribution_name)
201
+
202
+
203
+ def id() -> str:
204
+ """
205
+ Return the distro ID of the current distribution, as a
206
+ machine-readable string.
207
+
208
+ For a number of OS distributions, the returned distro ID value is
209
+ *reliable*, in the sense that it is documented and that it does not change
210
+ across releases of the distribution.
211
+
212
+ This package maintains the following reliable distro ID values:
213
+
214
+ ============== =========================================
215
+ Distro ID Distribution
216
+ ============== =========================================
217
+ "ubuntu" Ubuntu
218
+ "debian" Debian
219
+ "rhel" RedHat Enterprise Linux
220
+ "centos" CentOS
221
+ "fedora" Fedora
222
+ "sles" SUSE Linux Enterprise Server
223
+ "opensuse" openSUSE
224
+ "amzn" Amazon Linux
225
+ "arch" Arch Linux
226
+ "buildroot" Buildroot
227
+ "cloudlinux" CloudLinux OS
228
+ "exherbo" Exherbo Linux
229
+ "gentoo" GenToo Linux
230
+ "ibm_powerkvm" IBM PowerKVM
231
+ "kvmibm" KVM for IBM z Systems
232
+ "linuxmint" Linux Mint
233
+ "mageia" Mageia
234
+ "mandriva" Mandriva Linux
235
+ "parallels" Parallels
236
+ "pidora" Pidora
237
+ "raspbian" Raspbian
238
+ "oracle" Oracle Linux (and Oracle Enterprise Linux)
239
+ "scientific" Scientific Linux
240
+ "slackware" Slackware
241
+ "xenserver" XenServer
242
+ "openbsd" OpenBSD
243
+ "netbsd" NetBSD
244
+ "freebsd" FreeBSD
245
+ "midnightbsd" MidnightBSD
246
+ "rocky" Rocky Linux
247
+ "aix" AIX
248
+ "guix" Guix System
249
+ "altlinux" ALT Linux
250
+ ============== =========================================
251
+
252
+ If you have a need to get distros for reliable IDs added into this set,
253
+ or if you find that the :func:`distro.id` function returns a different
254
+ distro ID for one of the listed distros, please create an issue in the
255
+ `distro issue tracker`_.
256
+
257
+ **Lookup hierarchy and transformations:**
258
+
259
+ First, the ID is obtained from the following sources, in the specified
260
+ order. The first available and non-empty value is used:
261
+
262
+ * the value of the "ID" attribute of the os-release file,
263
+
264
+ * the value of the "Distributor ID" attribute returned by the lsb_release
265
+ command,
266
+
267
+ * the first part of the file name of the distro release file,
268
+
269
+ The so determined ID value then passes the following transformations,
270
+ before it is returned by this method:
271
+
272
+ * it is translated to lower case,
273
+
274
+ * blanks (which should not be there anyway) are translated to underscores,
275
+
276
+ * a normalization of the ID is performed, based upon
277
+ `normalization tables`_. The purpose of this normalization is to ensure
278
+ that the ID is as reliable as possible, even across incompatible changes
279
+ in the OS distributions. A common reason for an incompatible change is
280
+ the addition of an os-release file, or the addition of the lsb_release
281
+ command, with ID values that differ from what was previously determined
282
+ from the distro release file name.
283
+ """
284
+ return _distro.id()
285
+
286
+
287
+ def name(pretty: bool = False) -> str:
288
+ """
289
+ Return the name of the current OS distribution, as a human-readable
290
+ string.
291
+
292
+ If *pretty* is false, the name is returned without version or codename.
293
+ (e.g. "CentOS Linux")
294
+
295
+ If *pretty* is true, the version and codename are appended.
296
+ (e.g. "CentOS Linux 7.1.1503 (Core)")
297
+
298
+ **Lookup hierarchy:**
299
+
300
+ The name is obtained from the following sources, in the specified order.
301
+ The first available and non-empty value is used:
302
+
303
+ * If *pretty* is false:
304
+
305
+ - the value of the "NAME" attribute of the os-release file,
306
+
307
+ - the value of the "Distributor ID" attribute returned by the lsb_release
308
+ command,
309
+
310
+ - the value of the "<name>" field of the distro release file.
311
+
312
+ * If *pretty* is true:
313
+
314
+ - the value of the "PRETTY_NAME" attribute of the os-release file,
315
+
316
+ - the value of the "Description" attribute returned by the lsb_release
317
+ command,
318
+
319
+ - the value of the "<name>" field of the distro release file, appended
320
+ with the value of the pretty version ("<version_id>" and "<codename>"
321
+ fields) of the distro release file, if available.
322
+ """
323
+ return _distro.name(pretty)
324
+
325
+
326
+ def version(pretty: bool = False, best: bool = False) -> str:
327
+ """
328
+ Return the version of the current OS distribution, as a human-readable
329
+ string.
330
+
331
+ If *pretty* is false, the version is returned without codename (e.g.
332
+ "7.0").
333
+
334
+ If *pretty* is true, the codename in parenthesis is appended, if the
335
+ codename is non-empty (e.g. "7.0 (Maipo)").
336
+
337
+ Some distributions provide version numbers with different precisions in
338
+ the different sources of distribution information. Examining the different
339
+ sources in a fixed priority order does not always yield the most precise
340
+ version (e.g. for Debian 8.2, or CentOS 7.1).
341
+
342
+ Some other distributions may not provide this kind of information. In these
343
+ cases, an empty string would be returned. This behavior can be observed
344
+ with rolling releases distributions (e.g. Arch Linux).
345
+
346
+ The *best* parameter can be used to control the approach for the returned
347
+ version:
348
+
349
+ If *best* is false, the first non-empty version number in priority order of
350
+ the examined sources is returned.
351
+
352
+ If *best* is true, the most precise version number out of all examined
353
+ sources is returned.
354
+
355
+ **Lookup hierarchy:**
356
+
357
+ In all cases, the version number is obtained from the following sources.
358
+ If *best* is false, this order represents the priority order:
359
+
360
+ * the value of the "VERSION_ID" attribute of the os-release file,
361
+ * the value of the "Release" attribute returned by the lsb_release
362
+ command,
363
+ * the version number parsed from the "<version_id>" field of the first line
364
+ of the distro release file,
365
+ * the version number parsed from the "PRETTY_NAME" attribute of the
366
+ os-release file, if it follows the format of the distro release files.
367
+ * the version number parsed from the "Description" attribute returned by
368
+ the lsb_release command, if it follows the format of the distro release
369
+ files.
370
+ """
371
+ return _distro.version(pretty, best)
372
+
373
+
374
+ def version_parts(best: bool = False) -> Tuple[str, str, str]:
375
+ """
376
+ Return the version of the current OS distribution as a tuple
377
+ ``(major, minor, build_number)`` with items as follows:
378
+
379
+ * ``major``: The result of :func:`distro.major_version`.
380
+
381
+ * ``minor``: The result of :func:`distro.minor_version`.
382
+
383
+ * ``build_number``: The result of :func:`distro.build_number`.
384
+
385
+ For a description of the *best* parameter, see the :func:`distro.version`
386
+ method.
387
+ """
388
+ return _distro.version_parts(best)
389
+
390
+
391
+ def major_version(best: bool = False) -> str:
392
+ """
393
+ Return the major version of the current OS distribution, as a string,
394
+ if provided.
395
+ Otherwise, the empty string is returned. The major version is the first
396
+ part of the dot-separated version string.
397
+
398
+ For a description of the *best* parameter, see the :func:`distro.version`
399
+ method.
400
+ """
401
+ return _distro.major_version(best)
402
+
403
+
404
+ def minor_version(best: bool = False) -> str:
405
+ """
406
+ Return the minor version of the current OS distribution, as a string,
407
+ if provided.
408
+ Otherwise, the empty string is returned. The minor version is the second
409
+ part of the dot-separated version string.
410
+
411
+ For a description of the *best* parameter, see the :func:`distro.version`
412
+ method.
413
+ """
414
+ return _distro.minor_version(best)
415
+
416
+
417
+ def build_number(best: bool = False) -> str:
418
+ """
419
+ Return the build number of the current OS distribution, as a string,
420
+ if provided.
421
+ Otherwise, the empty string is returned. The build number is the third part
422
+ of the dot-separated version string.
423
+
424
+ For a description of the *best* parameter, see the :func:`distro.version`
425
+ method.
426
+ """
427
+ return _distro.build_number(best)
428
+
429
+
430
+ def like() -> str:
431
+ """
432
+ Return a space-separated list of distro IDs of distributions that are
433
+ closely related to the current OS distribution in regards to packaging
434
+ and programming interfaces, for example distributions the current
435
+ distribution is a derivative from.
436
+
437
+ **Lookup hierarchy:**
438
+
439
+ This information item is only provided by the os-release file.
440
+ For details, see the description of the "ID_LIKE" attribute in the
441
+ `os-release man page
442
+ <http://www.freedesktop.org/software/systemd/man/os-release.html>`_.
443
+ """
444
+ return _distro.like()
445
+
446
+
447
+ def codename() -> str:
448
+ """
449
+ Return the codename for the release of the current OS distribution,
450
+ as a string.
451
+
452
+ If the distribution does not have a codename, an empty string is returned.
453
+
454
+ Note that the returned codename is not always really a codename. For
455
+ example, openSUSE returns "x86_64". This function does not handle such
456
+ cases in any special way and just returns the string it finds, if any.
457
+
458
+ **Lookup hierarchy:**
459
+
460
+ * the codename within the "VERSION" attribute of the os-release file, if
461
+ provided,
462
+
463
+ * the value of the "Codename" attribute returned by the lsb_release
464
+ command,
465
+
466
+ * the value of the "<codename>" field of the distro release file.
467
+ """
468
+ return _distro.codename()
469
+
470
+
471
+ def info(pretty: bool = False, best: bool = False) -> InfoDict:
472
+ """
473
+ Return certain machine-readable information items about the current OS
474
+ distribution in a dictionary, as shown in the following example:
475
+
476
+ .. sourcecode:: python
477
+
478
+ {
479
+ 'id': 'rhel',
480
+ 'version': '7.0',
481
+ 'version_parts': {
482
+ 'major': '7',
483
+ 'minor': '0',
484
+ 'build_number': ''
485
+ },
486
+ 'like': 'fedora',
487
+ 'codename': 'Maipo'
488
+ }
489
+
490
+ The dictionary structure and keys are always the same, regardless of which
491
+ information items are available in the underlying data sources. The values
492
+ for the various keys are as follows:
493
+
494
+ * ``id``: The result of :func:`distro.id`.
495
+
496
+ * ``version``: The result of :func:`distro.version`.
497
+
498
+ * ``version_parts -> major``: The result of :func:`distro.major_version`.
499
+
500
+ * ``version_parts -> minor``: The result of :func:`distro.minor_version`.
501
+
502
+ * ``version_parts -> build_number``: The result of
503
+ :func:`distro.build_number`.
504
+
505
+ * ``like``: The result of :func:`distro.like`.
506
+
507
+ * ``codename``: The result of :func:`distro.codename`.
508
+
509
+ For a description of the *pretty* and *best* parameters, see the
510
+ :func:`distro.version` method.
511
+ """
512
+ return _distro.info(pretty, best)
513
+
514
+
515
+ def os_release_info() -> Dict[str, str]:
516
+ """
517
+ Return a dictionary containing key-value pairs for the information items
518
+ from the os-release file data source of the current OS distribution.
519
+
520
+ See `os-release file`_ for details about these information items.
521
+ """
522
+ return _distro.os_release_info()
523
+
524
+
525
+ def lsb_release_info() -> Dict[str, str]:
526
+ """
527
+ Return a dictionary containing key-value pairs for the information items
528
+ from the lsb_release command data source of the current OS distribution.
529
+
530
+ See `lsb_release command output`_ for details about these information
531
+ items.
532
+ """
533
+ return _distro.lsb_release_info()
534
+
535
+
536
+ def distro_release_info() -> Dict[str, str]:
537
+ """
538
+ Return a dictionary containing key-value pairs for the information items
539
+ from the distro release file data source of the current OS distribution.
540
+
541
+ See `distro release file`_ for details about these information items.
542
+ """
543
+ return _distro.distro_release_info()
544
+
545
+
546
+ def uname_info() -> Dict[str, str]:
547
+ """
548
+ Return a dictionary containing key-value pairs for the information items
549
+ from the distro release file data source of the current OS distribution.
550
+ """
551
+ return _distro.uname_info()
552
+
553
+
554
+ def os_release_attr(attribute: str) -> str:
555
+ """
556
+ Return a single named information item from the os-release file data source
557
+ of the current OS distribution.
558
+
559
+ Parameters:
560
+
561
+ * ``attribute`` (string): Key of the information item.
562
+
563
+ Returns:
564
+
565
+ * (string): Value of the information item, if the item exists.
566
+ The empty string, if the item does not exist.
567
+
568
+ See `os-release file`_ for details about these information items.
569
+ """
570
+ return _distro.os_release_attr(attribute)
571
+
572
+
573
+ def lsb_release_attr(attribute: str) -> str:
574
+ """
575
+ Return a single named information item from the lsb_release command output
576
+ data source of the current OS distribution.
577
+
578
+ Parameters:
579
+
580
+ * ``attribute`` (string): Key of the information item.
581
+
582
+ Returns:
583
+
584
+ * (string): Value of the information item, if the item exists.
585
+ The empty string, if the item does not exist.
586
+
587
+ See `lsb_release command output`_ for details about these information
588
+ items.
589
+ """
590
+ return _distro.lsb_release_attr(attribute)
591
+
592
+
593
+ def distro_release_attr(attribute: str) -> str:
594
+ """
595
+ Return a single named information item from the distro release file
596
+ data source of the current OS distribution.
597
+
598
+ Parameters:
599
+
600
+ * ``attribute`` (string): Key of the information item.
601
+
602
+ Returns:
603
+
604
+ * (string): Value of the information item, if the item exists.
605
+ The empty string, if the item does not exist.
606
+
607
+ See `distro release file`_ for details about these information items.
608
+ """
609
+ return _distro.distro_release_attr(attribute)
610
+
611
+
612
+ def uname_attr(attribute: str) -> str:
613
+ """
614
+ Return a single named information item from the distro release file
615
+ data source of the current OS distribution.
616
+
617
+ Parameters:
618
+
619
+ * ``attribute`` (string): Key of the information item.
620
+
621
+ Returns:
622
+
623
+ * (string): Value of the information item, if the item exists.
624
+ The empty string, if the item does not exist.
625
+ """
626
+ return _distro.uname_attr(attribute)
627
+
628
+
629
+ try:
630
+ from functools import cached_property
631
+ except ImportError:
632
+ # Python < 3.8
633
+ class cached_property: # type: ignore
634
+ """A version of @property which caches the value. On access, it calls the
635
+ underlying function and sets the value in `__dict__` so future accesses
636
+ will not re-call the property.
637
+ """
638
+
639
+ def __init__(self, f: Callable[[Any], Any]) -> None:
640
+ self._fname = f.__name__
641
+ self._f = f
642
+
643
+ def __get__(self, obj: Any, owner: Type[Any]) -> Any:
644
+ assert obj is not None, f"call {self._fname} on an instance"
645
+ ret = obj.__dict__[self._fname] = self._f(obj)
646
+ return ret
647
+
648
+
649
+ class LinuxDistribution:
650
+ """
651
+ Provides information about a OS distribution.
652
+
653
+ This package creates a private module-global instance of this class with
654
+ default initialization arguments, that is used by the
655
+ `consolidated accessor functions`_ and `single source accessor functions`_.
656
+ By using default initialization arguments, that module-global instance
657
+ returns data about the current OS distribution (i.e. the distro this
658
+ package runs on).
659
+
660
+ Normally, it is not necessary to create additional instances of this class.
661
+ However, in situations where control is needed over the exact data sources
662
+ that are used, instances of this class can be created with a specific
663
+ distro release file, or a specific os-release file, or without invoking the
664
+ lsb_release command.
665
+ """
666
+
667
+ def __init__(
668
+ self,
669
+ include_lsb: Optional[bool] = None,
670
+ os_release_file: str = "",
671
+ distro_release_file: str = "",
672
+ include_uname: Optional[bool] = None,
673
+ root_dir: Optional[str] = None,
674
+ include_oslevel: Optional[bool] = None,
675
+ ) -> None:
676
+ """
677
+ The initialization method of this class gathers information from the
678
+ available data sources, and stores that in private instance attributes.
679
+ Subsequent access to the information items uses these private instance
680
+ attributes, so that the data sources are read only once.
681
+
682
+ Parameters:
683
+
684
+ * ``include_lsb`` (bool): Controls whether the
685
+ `lsb_release command output`_ is included as a data source.
686
+
687
+ If the lsb_release command is not available in the program execution
688
+ path, the data source for the lsb_release command will be empty.
689
+
690
+ * ``os_release_file`` (string): The path name of the
691
+ `os-release file`_ that is to be used as a data source.
692
+
693
+ An empty string (the default) will cause the default path name to
694
+ be used (see `os-release file`_ for details).
695
+
696
+ If the specified or defaulted os-release file does not exist, the
697
+ data source for the os-release file will be empty.
698
+
699
+ * ``distro_release_file`` (string): The path name of the
700
+ `distro release file`_ that is to be used as a data source.
701
+
702
+ An empty string (the default) will cause a default search algorithm
703
+ to be used (see `distro release file`_ for details).
704
+
705
+ If the specified distro release file does not exist, or if no default
706
+ distro release file can be found, the data source for the distro
707
+ release file will be empty.
708
+
709
+ * ``include_uname`` (bool): Controls whether uname command output is
710
+ included as a data source. If the uname command is not available in
711
+ the program execution path the data source for the uname command will
712
+ be empty.
713
+
714
+ * ``root_dir`` (string): The absolute path to the root directory to use
715
+ to find distro-related information files. Note that ``include_*``
716
+ parameters must not be enabled in combination with ``root_dir``.
717
+
718
+ * ``include_oslevel`` (bool): Controls whether (AIX) oslevel command
719
+ output is included as a data source. If the oslevel command is not
720
+ available in the program execution path the data source will be
721
+ empty.
722
+
723
+ Public instance attributes:
724
+
725
+ * ``os_release_file`` (string): The path name of the
726
+ `os-release file`_ that is actually used as a data source. The
727
+ empty string if no distro release file is used as a data source.
728
+
729
+ * ``distro_release_file`` (string): The path name of the
730
+ `distro release file`_ that is actually used as a data source. The
731
+ empty string if no distro release file is used as a data source.
732
+
733
+ * ``include_lsb`` (bool): The result of the ``include_lsb`` parameter.
734
+ This controls whether the lsb information will be loaded.
735
+
736
+ * ``include_uname`` (bool): The result of the ``include_uname``
737
+ parameter. This controls whether the uname information will
738
+ be loaded.
739
+
740
+ * ``include_oslevel`` (bool): The result of the ``include_oslevel``
741
+ parameter. This controls whether (AIX) oslevel information will be
742
+ loaded.
743
+
744
+ * ``root_dir`` (string): The result of the ``root_dir`` parameter.
745
+ The absolute path to the root directory to use to find distro-related
746
+ information files.
747
+
748
+ Raises:
749
+
750
+ * :py:exc:`ValueError`: Initialization parameters combination is not
751
+ supported.
752
+
753
+ * :py:exc:`OSError`: Some I/O issue with an os-release file or distro
754
+ release file.
755
+
756
+ * :py:exc:`UnicodeError`: A data source has unexpected characters or
757
+ uses an unexpected encoding.
758
+ """
759
+ self.root_dir = root_dir
760
+ self.etc_dir = os.path.join(root_dir, "etc") if root_dir else _UNIXCONFDIR
761
+ self.usr_lib_dir = (
762
+ os.path.join(root_dir, "usr/lib") if root_dir else _UNIXUSRLIBDIR
763
+ )
764
+
765
+ if os_release_file:
766
+ self.os_release_file = os_release_file
767
+ else:
768
+ etc_dir_os_release_file = os.path.join(self.etc_dir, _OS_RELEASE_BASENAME)
769
+ usr_lib_os_release_file = os.path.join(
770
+ self.usr_lib_dir, _OS_RELEASE_BASENAME
771
+ )
772
+
773
+ # NOTE: The idea is to respect order **and** have it set
774
+ # at all times for API backwards compatibility.
775
+ if os.path.isfile(etc_dir_os_release_file) or not os.path.isfile(
776
+ usr_lib_os_release_file
777
+ ):
778
+ self.os_release_file = etc_dir_os_release_file
779
+ else:
780
+ self.os_release_file = usr_lib_os_release_file
781
+
782
+ self.distro_release_file = distro_release_file or "" # updated later
783
+
784
+ is_root_dir_defined = root_dir is not None
785
+ if is_root_dir_defined and (include_lsb or include_uname or include_oslevel):
786
+ raise ValueError(
787
+ "Including subprocess data sources from specific root_dir is disallowed"
788
+ " to prevent false information"
789
+ )
790
+ self.include_lsb = (
791
+ include_lsb if include_lsb is not None else not is_root_dir_defined
792
+ )
793
+ self.include_uname = (
794
+ include_uname if include_uname is not None else not is_root_dir_defined
795
+ )
796
+ self.include_oslevel = (
797
+ include_oslevel if include_oslevel is not None else not is_root_dir_defined
798
+ )
799
+
800
+ def __repr__(self) -> str:
801
+ """Return repr of all info"""
802
+ return (
803
+ "LinuxDistribution("
804
+ "os_release_file={self.os_release_file!r}, "
805
+ "distro_release_file={self.distro_release_file!r}, "
806
+ "include_lsb={self.include_lsb!r}, "
807
+ "include_uname={self.include_uname!r}, "
808
+ "include_oslevel={self.include_oslevel!r}, "
809
+ "root_dir={self.root_dir!r}, "
810
+ "_os_release_info={self._os_release_info!r}, "
811
+ "_lsb_release_info={self._lsb_release_info!r}, "
812
+ "_distro_release_info={self._distro_release_info!r}, "
813
+ "_uname_info={self._uname_info!r}, "
814
+ "_oslevel_info={self._oslevel_info!r})".format(self=self)
815
+ )
816
+
817
+ def linux_distribution(
818
+ self, full_distribution_name: bool = True
819
+ ) -> Tuple[str, str, str]:
820
+ """
821
+ Return information about the OS distribution that is compatible
822
+ with Python's :func:`platform.linux_distribution`, supporting a subset
823
+ of its parameters.
824
+
825
+ For details, see :func:`distro.linux_distribution`.
826
+ """
827
+ return (
828
+ self.name() if full_distribution_name else self.id(),
829
+ self.version(),
830
+ self._os_release_info.get("release_codename") or self.codename(),
831
+ )
832
+
833
+ def id(self) -> str:
834
+ """Return the distro ID of the OS distribution, as a string.
835
+
836
+ For details, see :func:`distro.id`.
837
+ """
838
+
839
+ def normalize(distro_id: str, table: Dict[str, str]) -> str:
840
+ distro_id = distro_id.lower().replace(" ", "_")
841
+ return table.get(distro_id, distro_id)
842
+
843
+ distro_id = self.os_release_attr("id")
844
+ if distro_id:
845
+ return normalize(distro_id, NORMALIZED_OS_ID)
846
+
847
+ distro_id = self.lsb_release_attr("distributor_id")
848
+ if distro_id:
849
+ return normalize(distro_id, NORMALIZED_LSB_ID)
850
+
851
+ distro_id = self.distro_release_attr("id")
852
+ if distro_id:
853
+ return normalize(distro_id, NORMALIZED_DISTRO_ID)
854
+
855
+ distro_id = self.uname_attr("id")
856
+ if distro_id:
857
+ return normalize(distro_id, NORMALIZED_DISTRO_ID)
858
+
859
+ return ""
860
+
861
+ def name(self, pretty: bool = False) -> str:
862
+ """
863
+ Return the name of the OS distribution, as a string.
864
+
865
+ For details, see :func:`distro.name`.
866
+ """
867
+ name = (
868
+ self.os_release_attr("name")
869
+ or self.lsb_release_attr("distributor_id")
870
+ or self.distro_release_attr("name")
871
+ or self.uname_attr("name")
872
+ )
873
+ if pretty:
874
+ name = self.os_release_attr("pretty_name") or self.lsb_release_attr(
875
+ "description"
876
+ )
877
+ if not name:
878
+ name = self.distro_release_attr("name") or self.uname_attr("name")
879
+ version = self.version(pretty=True)
880
+ if version:
881
+ name = f"{name} {version}"
882
+ return name or ""
883
+
884
+ def version(self, pretty: bool = False, best: bool = False) -> str:
885
+ """
886
+ Return the version of the OS distribution, as a string.
887
+
888
+ For details, see :func:`distro.version`.
889
+ """
890
+ versions = [
891
+ self.os_release_attr("version_id"),
892
+ self.lsb_release_attr("release"),
893
+ self.distro_release_attr("version_id"),
894
+ self._parse_distro_release_content(self.os_release_attr("pretty_name")).get(
895
+ "version_id", ""
896
+ ),
897
+ self._parse_distro_release_content(
898
+ self.lsb_release_attr("description")
899
+ ).get("version_id", ""),
900
+ self.uname_attr("release"),
901
+ ]
902
+ if self.uname_attr("id").startswith("aix"):
903
+ # On AIX platforms, prefer oslevel command output.
904
+ versions.insert(0, self.oslevel_info())
905
+ elif self.id() == "debian" or "debian" in self.like().split():
906
+ # On Debian-like, add debian_version file content to candidates list.
907
+ versions.append(self._debian_version)
908
+ version = ""
909
+ if best:
910
+ # This algorithm uses the last version in priority order that has
911
+ # the best precision. If the versions are not in conflict, that
912
+ # does not matter; otherwise, using the last one instead of the
913
+ # first one might be considered a surprise.
914
+ for v in versions:
915
+ if v.count(".") > version.count(".") or version == "":
916
+ version = v
917
+ else:
918
+ for v in versions:
919
+ if v != "":
920
+ version = v
921
+ break
922
+ if pretty and version and self.codename():
923
+ version = f"{version} ({self.codename()})"
924
+ return version
925
+
926
+ def version_parts(self, best: bool = False) -> Tuple[str, str, str]:
927
+ """
928
+ Return the version of the OS distribution, as a tuple of version
929
+ numbers.
930
+
931
+ For details, see :func:`distro.version_parts`.
932
+ """
933
+ version_str = self.version(best=best)
934
+ if version_str:
935
+ version_regex = re.compile(r"(\d+)\.?(\d+)?\.?(\d+)?")
936
+ matches = version_regex.match(version_str)
937
+ if matches:
938
+ major, minor, build_number = matches.groups()
939
+ return major, minor or "", build_number or ""
940
+ return "", "", ""
941
+
942
+ def major_version(self, best: bool = False) -> str:
943
+ """
944
+ Return the major version number of the current distribution.
945
+
946
+ For details, see :func:`distro.major_version`.
947
+ """
948
+ return self.version_parts(best)[0]
949
+
950
+ def minor_version(self, best: bool = False) -> str:
951
+ """
952
+ Return the minor version number of the current distribution.
953
+
954
+ For details, see :func:`distro.minor_version`.
955
+ """
956
+ return self.version_parts(best)[1]
957
+
958
+ def build_number(self, best: bool = False) -> str:
959
+ """
960
+ Return the build number of the current distribution.
961
+
962
+ For details, see :func:`distro.build_number`.
963
+ """
964
+ return self.version_parts(best)[2]
965
+
966
+ def like(self) -> str:
967
+ """
968
+ Return the IDs of distributions that are like the OS distribution.
969
+
970
+ For details, see :func:`distro.like`.
971
+ """
972
+ return self.os_release_attr("id_like") or ""
973
+
974
+ def codename(self) -> str:
975
+ """
976
+ Return the codename of the OS distribution.
977
+
978
+ For details, see :func:`distro.codename`.
979
+ """
980
+ try:
981
+ # Handle os_release specially since distros might purposefully set
982
+ # this to empty string to have no codename
983
+ return self._os_release_info["codename"]
984
+ except KeyError:
985
+ return (
986
+ self.lsb_release_attr("codename")
987
+ or self.distro_release_attr("codename")
988
+ or ""
989
+ )
990
+
991
+ def info(self, pretty: bool = False, best: bool = False) -> InfoDict:
992
+ """
993
+ Return certain machine-readable information about the OS
994
+ distribution.
995
+
996
+ For details, see :func:`distro.info`.
997
+ """
998
+ return InfoDict(
999
+ id=self.id(),
1000
+ version=self.version(pretty, best),
1001
+ version_parts=VersionDict(
1002
+ major=self.major_version(best),
1003
+ minor=self.minor_version(best),
1004
+ build_number=self.build_number(best),
1005
+ ),
1006
+ like=self.like(),
1007
+ codename=self.codename(),
1008
+ )
1009
+
1010
+ def os_release_info(self) -> Dict[str, str]:
1011
+ """
1012
+ Return a dictionary containing key-value pairs for the information
1013
+ items from the os-release file data source of the OS distribution.
1014
+
1015
+ For details, see :func:`distro.os_release_info`.
1016
+ """
1017
+ return self._os_release_info
1018
+
1019
+ def lsb_release_info(self) -> Dict[str, str]:
1020
+ """
1021
+ Return a dictionary containing key-value pairs for the information
1022
+ items from the lsb_release command data source of the OS
1023
+ distribution.
1024
+
1025
+ For details, see :func:`distro.lsb_release_info`.
1026
+ """
1027
+ return self._lsb_release_info
1028
+
1029
+ def distro_release_info(self) -> Dict[str, str]:
1030
+ """
1031
+ Return a dictionary containing key-value pairs for the information
1032
+ items from the distro release file data source of the OS
1033
+ distribution.
1034
+
1035
+ For details, see :func:`distro.distro_release_info`.
1036
+ """
1037
+ return self._distro_release_info
1038
+
1039
+ def uname_info(self) -> Dict[str, str]:
1040
+ """
1041
+ Return a dictionary containing key-value pairs for the information
1042
+ items from the uname command data source of the OS distribution.
1043
+
1044
+ For details, see :func:`distro.uname_info`.
1045
+ """
1046
+ return self._uname_info
1047
+
1048
+ def oslevel_info(self) -> str:
1049
+ """
1050
+ Return AIX' oslevel command output.
1051
+ """
1052
+ return self._oslevel_info
1053
+
1054
+ def os_release_attr(self, attribute: str) -> str:
1055
+ """
1056
+ Return a single named information item from the os-release file data
1057
+ source of the OS distribution.
1058
+
1059
+ For details, see :func:`distro.os_release_attr`.
1060
+ """
1061
+ return self._os_release_info.get(attribute, "")
1062
+
1063
+ def lsb_release_attr(self, attribute: str) -> str:
1064
+ """
1065
+ Return a single named information item from the lsb_release command
1066
+ output data source of the OS distribution.
1067
+
1068
+ For details, see :func:`distro.lsb_release_attr`.
1069
+ """
1070
+ return self._lsb_release_info.get(attribute, "")
1071
+
1072
+ def distro_release_attr(self, attribute: str) -> str:
1073
+ """
1074
+ Return a single named information item from the distro release file
1075
+ data source of the OS distribution.
1076
+
1077
+ For details, see :func:`distro.distro_release_attr`.
1078
+ """
1079
+ return self._distro_release_info.get(attribute, "")
1080
+
1081
+ def uname_attr(self, attribute: str) -> str:
1082
+ """
1083
+ Return a single named information item from the uname command
1084
+ output data source of the OS distribution.
1085
+
1086
+ For details, see :func:`distro.uname_attr`.
1087
+ """
1088
+ return self._uname_info.get(attribute, "")
1089
+
1090
+ @cached_property
1091
+ def _os_release_info(self) -> Dict[str, str]:
1092
+ """
1093
+ Get the information items from the specified os-release file.
1094
+
1095
+ Returns:
1096
+ A dictionary containing all information items.
1097
+ """
1098
+ if os.path.isfile(self.os_release_file):
1099
+ with open(self.os_release_file, encoding="utf-8") as release_file:
1100
+ return self._parse_os_release_content(release_file)
1101
+ return {}
1102
+
1103
+ @staticmethod
1104
+ def _parse_os_release_content(lines: TextIO) -> Dict[str, str]:
1105
+ """
1106
+ Parse the lines of an os-release file.
1107
+
1108
+ Parameters:
1109
+
1110
+ * lines: Iterable through the lines in the os-release file.
1111
+ Each line must be a unicode string or a UTF-8 encoded byte
1112
+ string.
1113
+
1114
+ Returns:
1115
+ A dictionary containing all information items.
1116
+ """
1117
+ props = {}
1118
+ lexer = shlex.shlex(lines, posix=True)
1119
+ lexer.whitespace_split = True
1120
+
1121
+ tokens = list(lexer)
1122
+ for token in tokens:
1123
+ # At this point, all shell-like parsing has been done (i.e.
1124
+ # comments processed, quotes and backslash escape sequences
1125
+ # processed, multi-line values assembled, trailing newlines
1126
+ # stripped, etc.), so the tokens are now either:
1127
+ # * variable assignments: var=value
1128
+ # * commands or their arguments (not allowed in os-release)
1129
+ # Ignore any tokens that are not variable assignments
1130
+ if "=" in token:
1131
+ k, v = token.split("=", 1)
1132
+ props[k.lower()] = v
1133
+
1134
+ if "version" in props:
1135
+ # extract release codename (if any) from version attribute
1136
+ match = re.search(r"\((\D+)\)|,\s*(\D+)", props["version"])
1137
+ if match:
1138
+ release_codename = match.group(1) or match.group(2)
1139
+ props["codename"] = props["release_codename"] = release_codename
1140
+
1141
+ if "version_codename" in props:
1142
+ # os-release added a version_codename field. Use that in
1143
+ # preference to anything else Note that some distros purposefully
1144
+ # do not have code names. They should be setting
1145
+ # version_codename=""
1146
+ props["codename"] = props["version_codename"]
1147
+ elif "ubuntu_codename" in props:
1148
+ # Same as above but a non-standard field name used on older Ubuntus
1149
+ props["codename"] = props["ubuntu_codename"]
1150
+
1151
+ return props
1152
+
1153
+ @cached_property
1154
+ def _lsb_release_info(self) -> Dict[str, str]:
1155
+ """
1156
+ Get the information items from the lsb_release command output.
1157
+
1158
+ Returns:
1159
+ A dictionary containing all information items.
1160
+ """
1161
+ if not self.include_lsb:
1162
+ return {}
1163
+ try:
1164
+ cmd = ("lsb_release", "-a")
1165
+ stdout = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
1166
+ # Command not found or lsb_release returned error
1167
+ except (OSError, subprocess.CalledProcessError):
1168
+ return {}
1169
+ content = self._to_str(stdout).splitlines()
1170
+ return self._parse_lsb_release_content(content)
1171
+
1172
+ @staticmethod
1173
+ def _parse_lsb_release_content(lines: Iterable[str]) -> Dict[str, str]:
1174
+ """
1175
+ Parse the output of the lsb_release command.
1176
+
1177
+ Parameters:
1178
+
1179
+ * lines: Iterable through the lines of the lsb_release output.
1180
+ Each line must be a unicode string or a UTF-8 encoded byte
1181
+ string.
1182
+
1183
+ Returns:
1184
+ A dictionary containing all information items.
1185
+ """
1186
+ props = {}
1187
+ for line in lines:
1188
+ kv = line.strip("\n").split(":", 1)
1189
+ if len(kv) != 2:
1190
+ # Ignore lines without colon.
1191
+ continue
1192
+ k, v = kv
1193
+ props.update({k.replace(" ", "_").lower(): v.strip()})
1194
+ return props
1195
+
1196
+ @cached_property
1197
+ def _uname_info(self) -> Dict[str, str]:
1198
+ if not self.include_uname:
1199
+ return {}
1200
+ try:
1201
+ cmd = ("uname", "-rs")
1202
+ stdout = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
1203
+ except OSError:
1204
+ return {}
1205
+ content = self._to_str(stdout).splitlines()
1206
+ return self._parse_uname_content(content)
1207
+
1208
+ @cached_property
1209
+ def _oslevel_info(self) -> str:
1210
+ if not self.include_oslevel:
1211
+ return ""
1212
+ try:
1213
+ stdout = subprocess.check_output("oslevel", stderr=subprocess.DEVNULL)
1214
+ except (OSError, subprocess.CalledProcessError):
1215
+ return ""
1216
+ return self._to_str(stdout).strip()
1217
+
1218
+ @cached_property
1219
+ def _debian_version(self) -> str:
1220
+ try:
1221
+ with open(
1222
+ os.path.join(self.etc_dir, "debian_version"), encoding="ascii"
1223
+ ) as fp:
1224
+ return fp.readline().rstrip()
1225
+ except FileNotFoundError:
1226
+ return ""
1227
+
1228
+ @staticmethod
1229
+ def _parse_uname_content(lines: Sequence[str]) -> Dict[str, str]:
1230
+ if not lines:
1231
+ return {}
1232
+ props = {}
1233
+ match = re.search(r"^([^\s]+)\s+([\d\.]+)", lines[0].strip())
1234
+ if match:
1235
+ name, version = match.groups()
1236
+
1237
+ # This is to prevent the Linux kernel version from
1238
+ # appearing as the 'best' version on otherwise
1239
+ # identifiable distributions.
1240
+ if name == "Linux":
1241
+ return {}
1242
+ props["id"] = name.lower()
1243
+ props["name"] = name
1244
+ props["release"] = version
1245
+ return props
1246
+
1247
+ @staticmethod
1248
+ def _to_str(bytestring: bytes) -> str:
1249
+ encoding = sys.getfilesystemencoding()
1250
+ return bytestring.decode(encoding)
1251
+
1252
+ @cached_property
1253
+ def _distro_release_info(self) -> Dict[str, str]:
1254
+ """
1255
+ Get the information items from the specified distro release file.
1256
+
1257
+ Returns:
1258
+ A dictionary containing all information items.
1259
+ """
1260
+ if self.distro_release_file:
1261
+ # If it was specified, we use it and parse what we can, even if
1262
+ # its file name or content does not match the expected pattern.
1263
+ distro_info = self._parse_distro_release_file(self.distro_release_file)
1264
+ basename = os.path.basename(self.distro_release_file)
1265
+ # The file name pattern for user-specified distro release files
1266
+ # is somewhat more tolerant (compared to when searching for the
1267
+ # file), because we want to use what was specified as best as
1268
+ # possible.
1269
+ match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename)
1270
+ else:
1271
+ try:
1272
+ basenames = [
1273
+ basename
1274
+ for basename in os.listdir(self.etc_dir)
1275
+ if basename not in _DISTRO_RELEASE_IGNORE_BASENAMES
1276
+ and os.path.isfile(os.path.join(self.etc_dir, basename))
1277
+ ]
1278
+ # We sort for repeatability in cases where there are multiple
1279
+ # distro specific files; e.g. CentOS, Oracle, Enterprise all
1280
+ # containing `redhat-release` on top of their own.
1281
+ basenames.sort()
1282
+ except OSError:
1283
+ # This may occur when /etc is not readable but we can't be
1284
+ # sure about the *-release files. Check common entries of
1285
+ # /etc for information. If they turn out to not be there the
1286
+ # error is handled in `_parse_distro_release_file()`.
1287
+ basenames = _DISTRO_RELEASE_BASENAMES
1288
+ for basename in basenames:
1289
+ match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename)
1290
+ if match is None:
1291
+ continue
1292
+ filepath = os.path.join(self.etc_dir, basename)
1293
+ distro_info = self._parse_distro_release_file(filepath)
1294
+ # The name is always present if the pattern matches.
1295
+ if "name" not in distro_info:
1296
+ continue
1297
+ self.distro_release_file = filepath
1298
+ break
1299
+ else: # the loop didn't "break": no candidate.
1300
+ return {}
1301
+
1302
+ if match is not None:
1303
+ distro_info["id"] = match.group(1)
1304
+
1305
+ # CloudLinux < 7: manually enrich info with proper id.
1306
+ if "cloudlinux" in distro_info.get("name", "").lower():
1307
+ distro_info["id"] = "cloudlinux"
1308
+
1309
+ return distro_info
1310
+
1311
+ def _parse_distro_release_file(self, filepath: str) -> Dict[str, str]:
1312
+ """
1313
+ Parse a distro release file.
1314
+
1315
+ Parameters:
1316
+
1317
+ * filepath: Path name of the distro release file.
1318
+
1319
+ Returns:
1320
+ A dictionary containing all information items.
1321
+ """
1322
+ try:
1323
+ with open(filepath, encoding="utf-8") as fp:
1324
+ # Only parse the first line. For instance, on SLES there
1325
+ # are multiple lines. We don't want them...
1326
+ return self._parse_distro_release_content(fp.readline())
1327
+ except OSError:
1328
+ # Ignore not being able to read a specific, seemingly version
1329
+ # related file.
1330
+ # See https://github.com/python-distro/distro/issues/162
1331
+ return {}
1332
+
1333
+ @staticmethod
1334
+ def _parse_distro_release_content(line: str) -> Dict[str, str]:
1335
+ """
1336
+ Parse a line from a distro release file.
1337
+
1338
+ Parameters:
1339
+ * line: Line from the distro release file. Must be a unicode string
1340
+ or a UTF-8 encoded byte string.
1341
+
1342
+ Returns:
1343
+ A dictionary containing all information items.
1344
+ """
1345
+ matches = _DISTRO_RELEASE_CONTENT_REVERSED_PATTERN.match(line.strip()[::-1])
1346
+ distro_info = {}
1347
+ if matches:
1348
+ # regexp ensures non-None
1349
+ distro_info["name"] = matches.group(3)[::-1]
1350
+ if matches.group(2):
1351
+ distro_info["version_id"] = matches.group(2)[::-1]
1352
+ if matches.group(1):
1353
+ distro_info["codename"] = matches.group(1)[::-1]
1354
+ elif line:
1355
+ distro_info["name"] = line.strip()
1356
+ return distro_info
1357
+
1358
+
1359
+ _distro = LinuxDistribution()
1360
+
1361
+
1362
+ def main() -> None:
1363
+ logger = logging.getLogger(__name__)
1364
+ logger.setLevel(logging.DEBUG)
1365
+ logger.addHandler(logging.StreamHandler(sys.stdout))
1366
+
1367
+ parser = argparse.ArgumentParser(description="OS distro info tool")
1368
+ parser.add_argument(
1369
+ "--json", "-j", help="Output in machine readable format", action="store_true"
1370
+ )
1371
+
1372
+ parser.add_argument(
1373
+ "--root-dir",
1374
+ "-r",
1375
+ type=str,
1376
+ dest="root_dir",
1377
+ help="Path to the root filesystem directory (defaults to /)",
1378
+ )
1379
+
1380
+ args = parser.parse_args()
1381
+
1382
+ if args.root_dir:
1383
+ dist = LinuxDistribution(
1384
+ include_lsb=False,
1385
+ include_uname=False,
1386
+ include_oslevel=False,
1387
+ root_dir=args.root_dir,
1388
+ )
1389
+ else:
1390
+ dist = _distro
1391
+
1392
+ if args.json:
1393
+ logger.info(json.dumps(dist.info(), indent=4, sort_keys=True))
1394
+ else:
1395
+ logger.info("Name: %s", dist.name(pretty=True))
1396
+ distribution_version = dist.version(pretty=True)
1397
+ logger.info("Version: %s", distribution_version)
1398
+ distribution_codename = dist.codename()
1399
+ logger.info("Codename: %s", distribution_codename)
1400
+
1401
+
1402
+ if __name__ == "__main__":
1403
+ main()
.venv/lib/python3.11/site-packages/distro/py.typed ADDED
File without changes
.venv/lib/python3.11/site-packages/gguf-0.10.0.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
.venv/lib/python3.11/site-packages/gguf-0.10.0.dist-info/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Georgi Gerganov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
.venv/lib/python3.11/site-packages/gguf-0.10.0.dist-info/METADATA ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.1
2
+ Name: gguf
3
+ Version: 0.10.0
4
+ Summary: Read and write ML models in GGUF for GGML
5
+ Home-page: https://ggml.ai
6
+ Keywords: ggml,gguf,llama.cpp
7
+ Author: GGML
8
+ Author-email: [email protected]
9
+ Requires-Python: >=3.8
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Requires-Dist: numpy (>=1.17)
19
+ Requires-Dist: pyyaml (>=5.1)
20
+ Requires-Dist: tqdm (>=4.27)
21
+ Project-URL: Repository, https://github.com/ggerganov/llama.cpp
22
+ Description-Content-Type: text/markdown
23
+
24
+ ## gguf
25
+
26
+ This is a Python package for writing binary files in the [GGUF](https://github.com/ggerganov/ggml/pull/302)
27
+ (GGML Universal File) format.
28
+
29
+ See [convert_hf_to_gguf.py](https://github.com/ggerganov/llama.cpp/blob/master/convert_hf_to_gguf.py)
30
+ as an example for its usage.
31
+
32
+ ## Installation
33
+ ```sh
34
+ pip install gguf
35
+ ```
36
+
37
+ ## API Examples/Simple Tools
38
+
39
+ [examples/writer.py](https://github.com/ggerganov/llama.cpp/blob/master/gguf-py/examples/writer.py) — Generates `example.gguf` in the current directory to demonstrate generating a GGUF file. Note that this file cannot be used as a model.
40
+
41
+ [scripts/gguf_dump.py](https://github.com/ggerganov/llama.cpp/blob/master/gguf-py/scripts/gguf_dump.py) — Dumps a GGUF file's metadata to the console.
42
+
43
+ [scripts/gguf_set_metadata.py](https://github.com/ggerganov/llama.cpp/blob/master/gguf-py/scripts/gguf_set_metadata.py) — Allows changing simple metadata values in a GGUF file by key.
44
+
45
+ [scripts/gguf_convert_endian.py](https://github.com/ggerganov/llama.cpp/blob/master/gguf-py/scripts/gguf_convert_endian.py) — Allows converting the endianness of GGUF files.
46
+
47
+ [scripts/gguf_new_metadata.py](https://github.com/ggerganov/llama.cpp/blob/master/gguf-py/scripts/gguf_new_metadata.py) — Copies a GGUF file with added/modified/removed metadata values.
48
+
49
+ ## Development
50
+ Maintainers who participate in development of this package are advised to install it in editable mode:
51
+
52
+ ```sh
53
+ cd /path/to/llama.cpp/gguf-py
54
+
55
+ pip install --editable .
56
+ ```
57
+
58
+ **Note**: This may require to upgrade your Pip installation, with a message saying that editable installation currently requires `setup.py`.
59
+ In this case, upgrade Pip to the latest:
60
+
61
+ ```sh
62
+ pip install --upgrade pip
63
+ ```
64
+
65
+ ## Automatic publishing with CI
66
+
67
+ There's a GitHub workflow to make a release automatically upon creation of tags in a specified format.
68
+
69
+ 1. Bump the version in `pyproject.toml`.
70
+ 2. Create a tag named `gguf-vx.x.x` where `x.x.x` is the semantic version number.
71
+
72
+ ```sh
73
+ git tag -a gguf-v1.0.0 -m "Version 1.0 release"
74
+ ```
75
+
76
+ 3. Push the tags.
77
+
78
+ ```sh
79
+ git push origin --tags
80
+ ```
81
+
82
+ ## Manual publishing
83
+ If you want to publish the package manually for any reason, you need to have `twine` and `build` installed:
84
+
85
+ ```sh
86
+ pip install build twine
87
+ ```
88
+
89
+ Then, follow these steps to release a new version:
90
+
91
+ 1. Bump the version in `pyproject.toml`.
92
+ 2. Build the package:
93
+
94
+ ```sh
95
+ python -m build
96
+ ```
97
+
98
+ 3. Upload the generated distribution archives:
99
+
100
+ ```sh
101
+ python -m twine upload dist/*
102
+ ```
103
+
104
+ ## Run Unit Tests
105
+
106
+ From root of this repository you can run this command to run all the unit tests
107
+
108
+ ```bash
109
+ python -m unittest discover ./gguf-py -v
110
+ ```
111
+
112
+ ## TODO
113
+ - [ ] Include conversion scripts as command line entry points in this package.
114
+
.venv/lib/python3.11/site-packages/gguf-0.10.0.dist-info/RECORD ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ../../../bin/gguf-convert-endian,sha256=W53Q9wLM4ktx91uKrLfyuFNGS7UCbZr-mA2U66A_W0E,276
2
+ ../../../bin/gguf-dump,sha256=v29_dyj4DF8zullVHEvLoQotNn0dgtrt8f-NjwDigFw,256
3
+ ../../../bin/gguf-new-metadata,sha256=UwjDwictRuL-TFKI2mlnkzB8YzGJSNWJ69870J9w64Y,272
4
+ ../../../bin/gguf-set-metadata,sha256=iqt1mYpW1z41SzKpVu0r6NLBVYPDc-k06JH7cmo-e9s,272
5
+ gguf-0.10.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
6
+ gguf-0.10.0.dist-info/LICENSE,sha256=73jH5mWeNMeYGU8NNE6AfHIt5wy8oTWe9UdyZh4Ryjg,1072
7
+ gguf-0.10.0.dist-info/METADATA,sha256=0jck7V9EOoT24ugiLaorfqFzhmN3eJM7lj-fyq8tvy8,3533
8
+ gguf-0.10.0.dist-info/RECORD,,
9
+ gguf-0.10.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
10
+ gguf-0.10.0.dist-info/entry_points.txt,sha256=6SBOHW2PZstAG6hvoQ63pyxPF8CIGjGLXZyG-NFFnAc,227
11
+ gguf/__init__.py,sha256=PM_AEEzX6ojGAodDt78_LIm19HRCXeA6IXpgcjINfC8,219
12
+ gguf/__pycache__/__init__.cpython-311.pyc,,
13
+ gguf/__pycache__/constants.cpython-311.pyc,,
14
+ gguf/__pycache__/gguf.cpython-311.pyc,,
15
+ gguf/__pycache__/gguf_reader.cpython-311.pyc,,
16
+ gguf/__pycache__/gguf_writer.cpython-311.pyc,,
17
+ gguf/__pycache__/lazy.cpython-311.pyc,,
18
+ gguf/__pycache__/metadata.cpython-311.pyc,,
19
+ gguf/__pycache__/quants.cpython-311.pyc,,
20
+ gguf/__pycache__/tensor_mapping.cpython-311.pyc,,
21
+ gguf/__pycache__/utility.cpython-311.pyc,,
22
+ gguf/__pycache__/vocab.cpython-311.pyc,,
23
+ gguf/constants.py,sha256=00pCXTqoWP36ZR9OcuxJfhezZfxqjUTKGCNvGMrkLGU,49158
24
+ gguf/gguf.py,sha256=8MDu7a0JEXhLUv_tjhYqDrWubVNc41cFvBYZbkZZenI,478
25
+ gguf/gguf_reader.py,sha256=0Y86qmxYfPNq3u_AiAwSnhU_G-V2SjXK2b7CM3MoPP4,12365
26
+ gguf/gguf_writer.py,sha256=ZWW_XwN6tyDIzBCwl6ARDwwRZ9TewNMV32IQaVYRNP8,35090
27
+ gguf/lazy.py,sha256=QwxFAtj-5nIm_a3mvLBezpShFuo-pjJhoAiXreK9ITQ,8601
28
+ gguf/metadata.py,sha256=nFEqgODwH6jYF3_jcycZkN4FjLnfXOQ7A73cLKZJb0Y,25722
29
+ gguf/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
+ gguf/quants.py,sha256=_6kmSprMfawH3gcPz9WbxnlXCeZQIYivf_HjfUvUkM0,57336
31
+ gguf/tensor_mapping.py,sha256=8CpqXKwKYFz6v11Fpzhe85hPcH18gnieh_FQsISpcVc,30893
32
+ gguf/utility.py,sha256=jbd1bduLFjjNAQhjghSyrRQfJ_kjiTFhRAZxm0oabZw,2934
33
+ gguf/vocab.py,sha256=N4PNulV8x_m7cdbmbUBF3nqQ0UXGTDi31oEIh3h8hAs,19046
34
+ scripts/__init__.py,sha256=-Az7fR5lhVb9GPB5U_BaDb8Xp706km53vSY7aXQYw9I,297
35
+ scripts/__pycache__/__init__.cpython-311.pyc,,
36
+ scripts/__pycache__/gguf_convert_endian.cpython-311.pyc,,
37
+ scripts/__pycache__/gguf_dump.cpython-311.pyc,,
38
+ scripts/__pycache__/gguf_hash.cpython-311.pyc,,
39
+ scripts/__pycache__/gguf_new_metadata.cpython-311.pyc,,
40
+ scripts/__pycache__/gguf_set_metadata.cpython-311.pyc,,
41
+ scripts/gguf_convert_endian.py,sha256=tcpe1O6xLTSetYD5T8dYcDN7cwiTWS-5sH7iFCP7ga8,5279
42
+ scripts/gguf_dump.py,sha256=Ej3XWrYupFOg-Bz-ff9EAN5hdmp2OCdEkd46D4PtZ58,21934
43
+ scripts/gguf_hash.py,sha256=DtzQ3xSdS8bHxdsp8ELQaBlaZiqqDBXzqtRSEzYTkhM,3711
44
+ scripts/gguf_new_metadata.py,sha256=bGuF8iXkElxIsr4mR952DHEBTosA9ob-UkF-zEqlPqo,10713
45
+ scripts/gguf_set_metadata.py,sha256=9jISgnh2atbwKh-68oN5b0wLxs0mYpXOWILjuqLTt-Q,4131
.venv/lib/python3.11/site-packages/gguf-0.10.0.dist-info/WHEEL ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 1.9.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
.venv/lib/python3.11/site-packages/gguf-0.10.0.dist-info/entry_points.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ [console_scripts]
2
+ gguf-convert-endian=scripts:gguf_convert_endian_entrypoint
3
+ gguf-dump=scripts:gguf_dump_entrypoint
4
+ gguf-new-metadata=scripts:gguf_new_metadata_entrypoint
5
+ gguf-set-metadata=scripts:gguf_set_metadata_entrypoint
6
+
.venv/lib/python3.11/site-packages/mistral_common/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ __version__ = "1.5.2"
.venv/lib/python3.11/site-packages/mistral_common/base.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel, ConfigDict
2
+
3
+
4
+ class MistralBase(BaseModel):
5
+ """
6
+ Base class for all Mistral Pydantic models.
7
+ """
8
+
9
+ model_config = ConfigDict(extra="forbid", validate_default=True, use_enum_values=True)
.venv/lib/python3.11/site-packages/mistral_common/exceptions.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+
3
+
4
+ class MistralCommonException(Exception):
5
+ message: str = "Internal server error"
6
+
7
+ def __init__(
8
+ self,
9
+ message: Optional[str] = None,
10
+ ) -> None:
11
+ if message:
12
+ self.message = message
13
+
14
+
15
+ class TokenizerException(MistralCommonException):
16
+ def __init__(self, message: str) -> None:
17
+ super().__init__(message)
18
+
19
+
20
+ class UnsupportedTokenizerFeatureException(MistralCommonException):
21
+ def __init__(self, message: str) -> None:
22
+ super().__init__(message)
23
+
24
+
25
+ class InvalidRequestException(MistralCommonException):
26
+ def __init__(self, message: str) -> None:
27
+ super().__init__(message)
28
+
29
+
30
+ class InvalidSystemPromptException(MistralCommonException):
31
+ def __init__(self, message: str) -> None:
32
+ super().__init__(message)
33
+
34
+
35
+ class InvalidMessageStructureException(MistralCommonException):
36
+ def __init__(self, message: str) -> None:
37
+ super().__init__(message)
38
+
39
+
40
+ class InvalidAssistantMessageException(MistralCommonException):
41
+ def __init__(self, message: str) -> None:
42
+ super().__init__(message)
43
+
44
+
45
+ class InvalidToolMessageException(MistralCommonException):
46
+ def __init__(self, message: str) -> None:
47
+ super().__init__(message)
48
+
49
+
50
+ class InvalidToolSchemaException(MistralCommonException):
51
+ def __init__(self, message: str) -> None:
52
+ super().__init__(message)
53
+
54
+
55
+ class InvalidUserMessageException(MistralCommonException):
56
+ def __init__(self, message: str) -> None:
57
+ super().__init__(message)
58
+
59
+
60
+ class InvalidFunctionCallException(MistralCommonException):
61
+ def __init__(self, message: str) -> None:
62
+ super().__init__(message)
63
+
64
+
65
+ class InvalidToolException(MistralCommonException):
66
+ def __init__(self, message: str) -> None:
67
+ super().__init__(message)
.venv/lib/python3.11/site-packages/mistral_common/multimodal.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import base64
2
+ import io
3
+ from typing import Union
4
+
5
+ import requests
6
+ from PIL import Image
7
+ from pydantic import BeforeValidator, PlainSerializer, SerializationInfo
8
+ from typing_extensions import Annotated
9
+
10
+ from mistral_common import __version__
11
+
12
+
13
+ def download_image(url: str) -> Image.Image:
14
+ headers = {"User-Agent": f"mistral-common/{__version__}"}
15
+ try:
16
+ # Make a request to download the image
17
+ response = requests.get(url, headers=headers)
18
+ response.raise_for_status() # Raise an error for bad responses (4xx, 5xx)
19
+
20
+ # Convert the image content to a PIL Image
21
+ img = Image.open(io.BytesIO(response.content))
22
+ return img
23
+
24
+ except requests.exceptions.RequestException as e:
25
+ raise RuntimeError(f"Error downloading the image from {url}: {e}.")
26
+ except Exception as e:
27
+ raise RuntimeError(f"Error converting to PIL image: {e}")
28
+
29
+
30
+ def maybe_load_image_from_str_or_bytes(x: Union[Image.Image, str, bytes]) -> Image.Image:
31
+ if isinstance(x, Image.Image):
32
+ return x
33
+ if isinstance(x, bytes):
34
+ try:
35
+ return Image.open(io.BytesIO(x))
36
+ except Exception:
37
+ raise RuntimeError("Encountered an error when loading image from bytes.")
38
+
39
+ try:
40
+ image = Image.open(io.BytesIO(base64.b64decode(x.encode("ascii"))))
41
+ return image
42
+ except Exception as e:
43
+ raise RuntimeError(
44
+ f"Encountered an error when loading image from bytes starting "
45
+ f"with '{x[:20]}'. Expected either a PIL.Image.Image or a base64 "
46
+ f"encoded string of bytes."
47
+ ) from e
48
+
49
+
50
+ def serialize_image_to_byte_str(im: Image.Image, info: SerializationInfo) -> str:
51
+ if hasattr(info, "context"):
52
+ context = info.context or {}
53
+ else:
54
+ context = {}
55
+
56
+ stream = io.BytesIO()
57
+ im_format = im.format or "PNG"
58
+ im.save(stream, format=im_format)
59
+ im_b64 = base64.b64encode(stream.getvalue()).decode("ascii")
60
+ if context and (max_image_b64_len := context.get("max_image_b64_len")):
61
+ return im_b64[:max_image_b64_len] + "..."
62
+ return im_b64
63
+
64
+
65
+ # A normal PIL image that supports serialization to b64 bytes string
66
+ SerializableImage = Annotated[
67
+ Image.Image,
68
+ BeforeValidator(maybe_load_image_from_str_or_bytes),
69
+ PlainSerializer(serialize_image_to_byte_str),
70
+ ]
.venv/lib/python3.11/site-packages/mistral_common/protocol/__init__.py ADDED
File without changes
.venv/lib/python3.11/site-packages/mistral_common/protocol/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (196 Bytes). View file
 
.venv/lib/python3.11/site-packages/mistral_common/protocol/__pycache__/base.cpython-311.pyc ADDED
Binary file (1.49 kB). View file
 
.venv/lib/python3.11/site-packages/mistral_common/protocol/__pycache__/utils.cpython-311.pyc ADDED
Binary file (476 Bytes). View file
 
.venv/lib/python3.11/site-packages/mistral_common/protocol/base.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+
3
+ from pydantic import Field
4
+
5
+ from mistral_common.base import MistralBase
6
+
7
+
8
+ class UsageInfo(MistralBase):
9
+ prompt_tokens: int = 0
10
+ total_tokens: int = 0
11
+ completion_tokens: Optional[int] = 0
12
+
13
+
14
+ class BaseCompletionRequest(MistralBase):
15
+ temperature: float = Field(default=0.7, ge=0.0, le=1.0)
16
+ top_p: float = Field(default=1.0, ge=0.0, le=1.0)
17
+ max_tokens: Optional[int] = Field(default=None, ge=0)
18
+ random_seed: Optional[int] = Field(default=None, ge=0)
.venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/__init__.py ADDED
File without changes
.venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/__pycache__/normalize.cpython-311.pyc ADDED
Binary file (15.2 kB). View file
 
.venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/__pycache__/request.cpython-311.pyc ADDED
Binary file (2.14 kB). View file
 
.venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/__pycache__/tool_calls.cpython-311.pyc ADDED
Binary file (3.07 kB). View file
 
.venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/__pycache__/validator.cpython-311.pyc ADDED
Binary file (16.9 kB). View file
 
.venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/messages.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from enum import Enum
2
+ from typing import List, Literal, Optional, TypeVar, Union
3
+
4
+ from pydantic import ConfigDict, Field
5
+ from typing_extensions import Annotated, TypeAlias
6
+
7
+ from mistral_common.base import MistralBase
8
+ from mistral_common.multimodal import SerializableImage
9
+ from mistral_common.protocol.instruct.tool_calls import ToolCall
10
+
11
+
12
+ class ChunkTypes(str, Enum):
13
+ text = "text"
14
+ image = "image"
15
+ image_url = "image_url"
16
+
17
+
18
+ class BaseContentChunk(MistralBase):
19
+ type: Literal[ChunkTypes.text, ChunkTypes.image, ChunkTypes.image_url]
20
+
21
+
22
+ class ImageChunk(BaseContentChunk):
23
+ type: Literal[ChunkTypes.image] = ChunkTypes.image
24
+ image: SerializableImage
25
+ model_config = ConfigDict(arbitrary_types_allowed=True)
26
+
27
+
28
+ class ImageURL(MistralBase):
29
+ url: str
30
+ detail: Optional[str] = None
31
+
32
+
33
+ class ImageURLChunk(BaseContentChunk):
34
+ """
35
+ {"type":"image_url","image_url":{"url":"data:image/png;base64,iVBORw0
36
+ """
37
+
38
+ type: Literal[ChunkTypes.image_url] = ChunkTypes.image_url
39
+ image_url: Union[ImageURL, str]
40
+
41
+ model_config = ConfigDict(arbitrary_types_allowed=True)
42
+
43
+ def get_url(self) -> str:
44
+ if isinstance(self.image_url, ImageURL):
45
+ return self.image_url.url
46
+ return self.image_url
47
+
48
+
49
+ class TextChunk(BaseContentChunk):
50
+ type: Literal[ChunkTypes.text] = ChunkTypes.text
51
+ text: str
52
+
53
+
54
+ ContentChunk = Annotated[Union[TextChunk, ImageChunk, ImageURLChunk], Field(discriminator="type")]
55
+
56
+
57
+ class Roles(str, Enum):
58
+ system = "system"
59
+ user = "user"
60
+ assistant = "assistant"
61
+ tool = "tool"
62
+
63
+
64
+ class BaseMessage(MistralBase):
65
+ role: Literal[Roles.system, Roles.user, Roles.assistant, Roles.tool]
66
+
67
+
68
+ class UserMessage(BaseMessage):
69
+ role: Literal[Roles.user] = Roles.user
70
+ content: Union[str, List[ContentChunk]]
71
+
72
+
73
+ class SystemMessage(BaseMessage):
74
+ role: Literal[Roles.system] = Roles.system
75
+ content: Union[str, List[ContentChunk]]
76
+
77
+
78
+ class AssistantMessage(BaseMessage):
79
+ role: Literal[Roles.assistant] = Roles.assistant
80
+ content: Optional[str] = None
81
+ tool_calls: Optional[List[ToolCall]] = None
82
+ prefix: bool = False
83
+
84
+
85
+ class FinetuningAssistantMessage(AssistantMessage):
86
+ weight: Optional[float] = None
87
+
88
+
89
+ class ToolMessage(BaseMessage):
90
+ content: str
91
+ role: Literal[Roles.tool] = Roles.tool
92
+ tool_call_id: Optional[str] = None
93
+
94
+ # Deprecated in V3 tokenization
95
+ name: Optional[str] = None
96
+
97
+
98
+ ChatMessage = Annotated[Union[SystemMessage, UserMessage, AssistantMessage, ToolMessage], Field(discriminator="role")]
99
+
100
+ FinetuningMessage = Annotated[
101
+ Union[SystemMessage, UserMessage, FinetuningAssistantMessage, ToolMessage],
102
+ Field(discriminator="role"),
103
+ ]
104
+
105
+ ChatMessageType = TypeVar("ChatMessageType", bound=ChatMessage)
106
+
107
+ # Used for type hinting in generic classes where we might override the message types
108
+ UserMessageType = TypeVar("UserMessageType", bound=UserMessage)
109
+ AssistantMessageType = TypeVar("AssistantMessageType", bound=AssistantMessage)
110
+ ToolMessageType = TypeVar("ToolMessageType", bound=ToolMessage)
111
+ SystemMessageType = TypeVar("SystemMessageType", bound=SystemMessage)
112
+
113
+ UATS: TypeAlias = Union[UserMessageType, AssistantMessageType, ToolMessageType, SystemMessageType]
.venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/normalize.py ADDED
@@ -0,0 +1,265 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from typing import Generic, List, Optional, Sequence, Type, Union
3
+
4
+ from mistral_common.protocol.instruct.messages import (
5
+ UATS,
6
+ AssistantMessage,
7
+ AssistantMessageType,
8
+ ContentChunk,
9
+ FinetuningAssistantMessage,
10
+ Roles,
11
+ SystemMessage,
12
+ SystemMessageType,
13
+ TextChunk,
14
+ ToolMessage,
15
+ ToolMessageType,
16
+ UserMessage,
17
+ UserMessageType,
18
+ )
19
+ from mistral_common.protocol.instruct.request import ChatCompletionRequest
20
+ from mistral_common.protocol.instruct.tool_calls import FunctionCall, Tool, ToolCall
21
+ from mistral_common.tokens.instruct.request import InstructRequest
22
+ from mistral_common.tokens.tokenizers.base import InstructRequestType, TokenizerVersion
23
+
24
+
25
+ class InstructRequestNormalizer(
26
+ Generic[UserMessageType, AssistantMessageType, ToolMessageType, SystemMessageType, InstructRequestType]
27
+ ):
28
+ """
29
+ Takes a ChatCompletionRequest and normalizes it into an InstructRequest.
30
+
31
+ The normalization process does several things such as:
32
+ - Aggregate consecutive messages of the same role
33
+ - Aggregate system prompts
34
+ - Normalize json content
35
+ - Normalize tool calls
36
+ """
37
+
38
+ system_prompt_in_begin: bool = False
39
+
40
+ def __init__(
41
+ self,
42
+ user_message_class: Type[UserMessageType],
43
+ assistant_message_class: Type[AssistantMessageType],
44
+ tool_message_class: Type[ToolMessageType],
45
+ system_message_class: Type[SystemMessageType],
46
+ instruct_request_class: Type[InstructRequestType],
47
+ ):
48
+ self._user_message_class = user_message_class
49
+ self._assistant_message_class = assistant_message_class
50
+ self._tool_message_class = tool_message_class
51
+ self._instruct_request_class = instruct_request_class
52
+ # this is unused but makes creation nicer
53
+ self._system_message_class = system_message_class
54
+
55
+ @staticmethod
56
+ def normalizer() -> "InstructRequestNormalizer":
57
+ return InstructRequestNormalizer(
58
+ UserMessage,
59
+ AssistantMessage,
60
+ ToolMessage,
61
+ SystemMessage,
62
+ InstructRequest[UATS, Tool],
63
+ )
64
+
65
+ def _normalize_json_content(self, content: Optional[str]) -> str:
66
+ if content is None or len(content) == 0:
67
+ return "{}"
68
+
69
+ try:
70
+ parsed_json = json.loads(content)
71
+ normalized_content = json.dumps(parsed_json, ensure_ascii=False)
72
+ except json.JSONDecodeError:
73
+ normalized_content = content
74
+ return normalized_content
75
+
76
+ def _aggregate_content_chunks(self, content: Union[str, List[TextChunk]], chunk_join_str: str = "\n\n") -> str:
77
+ if isinstance(content, list):
78
+ return chunk_join_str.join([chunk.text for chunk in content])
79
+ else:
80
+ return content
81
+
82
+ def _aggregate_system_prompts(self, request: ChatCompletionRequest[UATS]) -> Optional[str]:
83
+ system_prompt: List[str] = []
84
+
85
+ for message in request.messages:
86
+ if message.role == Roles.system and message.content:
87
+ system_prompt.append(self._aggregate_content_chunks(message.content))
88
+
89
+ return "\n\n".join(system_prompt) if len(system_prompt) else None
90
+
91
+ def _aggregate_tool_messages(self, messages: List[UATS]) -> List[ToolMessageType]:
92
+ """
93
+ We currently do not do any aggregation for tool messages, but we normalize the json content
94
+ """
95
+ tool_messages: List[ToolMessageType] = []
96
+ for message in messages:
97
+ assert isinstance(message, self._tool_message_class), "Expected tool message"
98
+ content = self._aggregate_content_chunks(message.content)
99
+ normalized_content = self._normalize_json_content(content)
100
+ tool_messages.append(
101
+ self._tool_message_class(
102
+ content=normalized_content, tool_call_id=message.tool_call_id, name=message.name
103
+ )
104
+ )
105
+
106
+ return tool_messages
107
+
108
+ def _normalize_tool_call(self, tool_call: ToolCall) -> ToolCall:
109
+ normalized_function_aruments = self._normalize_json_content(tool_call.function.arguments)
110
+ return ToolCall(
111
+ function=FunctionCall(name=tool_call.function.name, arguments=normalized_function_aruments),
112
+ id=tool_call.id,
113
+ )
114
+
115
+ def _aggregate_assistant_messages(self, messages: List[UATS]) -> AssistantMessageType:
116
+ aggregated_content: List[str] = []
117
+ tool_calls: List[ToolCall] = []
118
+ prefix: bool = False
119
+ weight: Optional[float] = None
120
+ for message in messages:
121
+ assert isinstance(message, self._assistant_message_class), "Expected assistant message"
122
+ if message.tool_calls is not None and len(message.tool_calls) > 0:
123
+ for tool_call in message.tool_calls:
124
+ normalized_tool_call = self._normalize_tool_call(tool_call)
125
+ tool_calls.append(normalized_tool_call)
126
+ elif message.content:
127
+ aggregated_content.append(self._aggregate_content_chunks(message.content))
128
+ prefix |= message.prefix
129
+ if isinstance(message, FinetuningAssistantMessage):
130
+ # Only FinetuningAssistantMessage can be weighted
131
+ if weight is not None:
132
+ assert (
133
+ weight == message.weight
134
+ ), "Expected weights of aggregated FinetuningAssistantMessage to be equal"
135
+ weight = message.weight
136
+
137
+ aggregated_message = self._assistant_message_class(
138
+ content="\n\n".join(aggregated_content) if len(aggregated_content) else None,
139
+ tool_calls=tool_calls or None,
140
+ prefix=prefix,
141
+ )
142
+
143
+ if weight is not None and hasattr(aggregated_message, "weight"):
144
+ aggregated_message.weight = weight
145
+ return aggregated_message
146
+
147
+ def _aggregate_user_messages(self, messages: List[UATS]) -> UserMessageType:
148
+ """
149
+ Just coalesce neighboring blocks of text
150
+ """
151
+ all_content: List[ContentChunk] = []
152
+ text_chunks: List[str] = []
153
+ for message in messages:
154
+ assert isinstance(message, self._user_message_class), f"Expected user message got {type(message)}"
155
+ if isinstance(message.content, str):
156
+ text_chunks.append(message.content)
157
+ else: # it's a List[ContentChunk]
158
+ for chunk in message.content:
159
+ if isinstance(chunk, TextChunk):
160
+ text_chunks.append(chunk.text)
161
+ else:
162
+ if text_chunks:
163
+ all_content.append(TextChunk(text="\n\n".join(text_chunks)))
164
+ text_chunks = []
165
+ all_content.append(chunk)
166
+
167
+ text_content = "\n\n".join(text_chunks) if text_chunks else ""
168
+
169
+ if not all_content:
170
+ # if no ContentChunk was passed, we return content as a str
171
+ return self._user_message_class(content=text_content)
172
+
173
+ if text_content:
174
+ # else we return a List of content chunks
175
+ all_content.append(TextChunk(text=text_content))
176
+
177
+ return self._user_message_class(content=all_content)
178
+
179
+ def _aggregate_role(self, messages: List[UATS], role: Optional[Roles]) -> Sequence[UATS]:
180
+ if role == Roles.tool:
181
+ return self._aggregate_tool_messages(messages)
182
+ elif role == Roles.assistant:
183
+ return [self._aggregate_assistant_messages(messages)]
184
+ elif role == Roles.user:
185
+ return [self._aggregate_user_messages(messages)]
186
+ else: # System messages are ignored
187
+ return []
188
+
189
+ def _aggregate_messages(self, request: ChatCompletionRequest[UATS]) -> List[UATS]:
190
+ aggregated_messages: List[UATS] = []
191
+ messages_to_aggregate: List[UATS] = []
192
+ current_role: Optional[Roles] = None
193
+ current_weight: Optional[float] = None
194
+
195
+ # Collect consecutive lists of messages with the same role and weight
196
+ for message in request.messages:
197
+ new_weight = getattr(message, "weight", None)
198
+ if current_role != message.role or (new_weight != current_weight):
199
+ aggregated_messages.extend(self._aggregate_role(messages_to_aggregate, current_role))
200
+ messages_to_aggregate.clear()
201
+ current_weight = new_weight
202
+ current_role = message.role
203
+ messages_to_aggregate.append(message)
204
+
205
+ # Add the last set of messages
206
+ aggregated_messages.extend(self._aggregate_role(messages_to_aggregate, current_role))
207
+
208
+ # If the first message is not a user message, or we didnt aggregate
209
+ # anything (all system messages) for example, add an empty user message
210
+ if len(aggregated_messages) == 0 or (
211
+ not self.system_prompt_in_begin and aggregated_messages[0].role != Roles.user
212
+ ):
213
+ aggregated_messages.insert(0, self._user_message_class(content=""))
214
+
215
+ return aggregated_messages
216
+
217
+ def from_chat_completion_request(self, request: ChatCompletionRequest[UATS]) -> InstructRequestType:
218
+ system_prompt = self._aggregate_system_prompts(request)
219
+ messages = self._aggregate_messages(request)
220
+
221
+ return self._instruct_request_class(
222
+ messages=messages, system_prompt=system_prompt, available_tools=request.tools
223
+ )
224
+
225
+
226
+ class InstructRequestNormalizerV7(InstructRequestNormalizer):
227
+ system_prompt_in_begin: bool = True
228
+
229
+ @staticmethod
230
+ def normalizer() -> "InstructRequestNormalizerV7":
231
+ return InstructRequestNormalizerV7(
232
+ UserMessage,
233
+ AssistantMessage,
234
+ ToolMessage,
235
+ SystemMessage,
236
+ InstructRequest[UATS, Tool],
237
+ )
238
+
239
+ def _aggregate_role(self, messages: List[UATS], role: Optional[Roles]) -> Sequence[UATS]:
240
+ if role == Roles.tool:
241
+ return self._aggregate_tool_messages(messages)
242
+ elif role == Roles.assistant:
243
+ return [self._aggregate_assistant_messages(messages)]
244
+ elif role == Roles.user:
245
+ return [self._aggregate_user_messages(messages)]
246
+ elif role == Roles.system:
247
+ return messages
248
+ else:
249
+ assert role is None and len(messages) == 0
250
+ return []
251
+
252
+ def _aggregate_system_prompts(self, request: ChatCompletionRequest[UATS]) -> Optional[str]:
253
+ raise NotImplementedError("We should not aggregate system prompts")
254
+
255
+ def from_chat_completion_request(self, request: ChatCompletionRequest[UATS]) -> InstructRequestType: # type: ignore[type-var]
256
+ messages = self._aggregate_messages(request)
257
+ return self._instruct_request_class(messages=messages, system_prompt=None, available_tools=request.tools) # type: ignore[no-any-return]
258
+
259
+
260
+ def normalizer_for_tokenizer_version(version: TokenizerVersion) -> InstructRequestNormalizer:
261
+ if version in {TokenizerVersion.v1, TokenizerVersion.v2, TokenizerVersion.v3}:
262
+ return InstructRequestNormalizer.normalizer()
263
+ elif version == TokenizerVersion.v7:
264
+ return InstructRequestNormalizerV7.normalizer()
265
+ raise ValueError(f"Unknown tokenizer version {version}")
.venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/request.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from enum import Enum
2
+ from typing import Generic, List, Optional
3
+
4
+ from pydantic import Field
5
+
6
+ from mistral_common.base import MistralBase
7
+ from mistral_common.protocol.base import BaseCompletionRequest
8
+ from mistral_common.protocol.instruct.messages import ChatMessageType
9
+ from mistral_common.protocol.instruct.tool_calls import Tool, ToolChoice
10
+
11
+
12
+ class ResponseFormats(str, Enum):
13
+ text: str = "text"
14
+ json: str = "json_object"
15
+
16
+
17
+ class ResponseFormat(MistralBase):
18
+ type: ResponseFormats = ResponseFormats.text
19
+
20
+
21
+ class ChatCompletionRequest(BaseCompletionRequest, Generic[ChatMessageType]):
22
+ model: Optional[str] = None
23
+ messages: List[ChatMessageType]
24
+ response_format: ResponseFormat = Field(default_factory=ResponseFormat)
25
+ tools: Optional[List[Tool]] = None
26
+ tool_choice: ToolChoice = ToolChoice.auto
27
+ truncate_for_context_length: bool = False
.venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/response.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ from enum import Enum
3
+ from typing import List, Optional
4
+
5
+ from pydantic import Field
6
+
7
+ from mistral_common.base import MistralBase
8
+ from mistral_common.protocol.base import UsageInfo
9
+ from mistral_common.protocol.instruct.tool_calls import ToolCall
10
+ from mistral_common.protocol.utils import random_uuid
11
+
12
+
13
+ class FinishReason(str, Enum):
14
+ stop: str = "stop"
15
+ length: str = "length"
16
+ model_length: str = "model_length"
17
+ error: str = "error"
18
+ tool_call: str = "tool_calls"
19
+
20
+
21
+ class ChatCompletionTokenLogprobs(MistralBase):
22
+ token: str
23
+ logprob: float
24
+ bytes: List[int]
25
+
26
+
27
+ class ChatCompletionResponseChoiceLogprobs(MistralBase):
28
+ content: List[ChatCompletionTokenLogprobs]
29
+
30
+
31
+ class DeltaMessage(MistralBase):
32
+ role: Optional[str] = None
33
+ content: Optional[str] = None
34
+ tool_calls: Optional[List[ToolCall]] = None
35
+
36
+
37
+ class ChatCompletionResponseChoice(MistralBase):
38
+ index: int
39
+ message: DeltaMessage
40
+ finish_reason: Optional[FinishReason] = None
41
+ logprobs: Optional[ChatCompletionResponseChoiceLogprobs] = None
42
+
43
+
44
+ class ChatCompletionResponse(MistralBase):
45
+ id: str = Field(default_factory=lambda: f"chatcmpl-{random_uuid()}")
46
+ object: str = "chat.completion"
47
+ created: int = Field(default_factory=lambda: int(time.time()))
48
+ model: str
49
+ choices: List[ChatCompletionResponseChoice]
50
+ usage: UsageInfo
51
+
52
+
53
+ class ChatCompletionResponseStreamChoice(MistralBase):
54
+ index: int
55
+ delta: DeltaMessage
56
+ finish_reason: Optional[FinishReason] = None
57
+ logprobs: Optional[ChatCompletionResponseChoiceLogprobs] = None
58
+
59
+
60
+ class ChatCompletionStreamResponse(MistralBase):
61
+ id: str = Field(default_factory=lambda: f"chatcmpl-{random_uuid()}")
62
+ object: str = "chat.completion.chunk"
63
+ created: int = Field(default_factory=lambda: int(time.time()))
64
+ model: str
65
+ choices: List[ChatCompletionResponseStreamChoice]
66
+ usage: Optional[UsageInfo] = None
.venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/tool_calls.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from enum import Enum
3
+ from typing import Any, Dict, TypeVar, Union
4
+
5
+ from pydantic import field_validator
6
+
7
+ from mistral_common.base import MistralBase
8
+
9
+
10
+ class Function(MistralBase):
11
+ name: str
12
+ description: str = ""
13
+ parameters: Dict[str, Any]
14
+
15
+
16
+ class ToolTypes(str, Enum):
17
+ function = "function"
18
+
19
+
20
+ class ToolChoice(str, Enum):
21
+ auto: str = "auto"
22
+ none: str = "none"
23
+ any: str = "any"
24
+
25
+
26
+ class Tool(MistralBase):
27
+ type: ToolTypes = ToolTypes.function
28
+ function: Function
29
+
30
+
31
+ class FunctionCall(MistralBase):
32
+ name: str
33
+ arguments: str
34
+
35
+ @field_validator("arguments", mode="before")
36
+ def validate_arguments(cls, v: Union[str, Dict[str, Any]]) -> str:
37
+ """
38
+ This is for backward compatibility
39
+ """
40
+ if isinstance(v, dict):
41
+ return json.dumps(v)
42
+ return v
43
+
44
+
45
+ class ToolCall(MistralBase):
46
+ id: str = "null" # required for V3 tokenization
47
+ type: ToolTypes = ToolTypes.function
48
+ function: FunctionCall
49
+
50
+
51
+ ToolType = TypeVar("ToolType", bound=Tool)
.venv/lib/python3.11/site-packages/mistral_common/protocol/instruct/validator.py ADDED
@@ -0,0 +1,328 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ from enum import Enum
3
+ from typing import Generic, List
4
+
5
+ from jsonschema import Draft7Validator, SchemaError
6
+
7
+ from mistral_common.exceptions import (
8
+ InvalidAssistantMessageException,
9
+ InvalidFunctionCallException,
10
+ InvalidMessageStructureException,
11
+ InvalidRequestException,
12
+ InvalidSystemPromptException,
13
+ InvalidToolException,
14
+ InvalidToolMessageException,
15
+ InvalidToolSchemaException,
16
+ )
17
+ from mistral_common.protocol.instruct.messages import (
18
+ UATS,
19
+ AssistantMessage,
20
+ AssistantMessageType,
21
+ FinetuningAssistantMessage,
22
+ Roles,
23
+ SystemMessageType,
24
+ ToolMessageType,
25
+ UserMessageType,
26
+ )
27
+ from mistral_common.protocol.instruct.request import ChatCompletionRequest
28
+ from mistral_common.protocol.instruct.tool_calls import (
29
+ Function,
30
+ FunctionCall,
31
+ Tool,
32
+ ToolCall,
33
+ )
34
+
35
+
36
+ class ValidationMode(Enum):
37
+ serving = "serving"
38
+ finetuning = "finetuning"
39
+ test = "test"
40
+
41
+
42
+ class MistralRequestValidator(Generic[UserMessageType, AssistantMessageType, ToolMessageType, SystemMessageType]):
43
+ def __init__(self, mode: ValidationMode = ValidationMode.test):
44
+ self._mode = mode
45
+
46
+ def validate_messages(self, messages: List[UATS]) -> None:
47
+ """
48
+ Validates the list of messages
49
+ """
50
+ self._validate_message_list_structure(messages)
51
+ self._validate_message_list_content(messages)
52
+
53
+ def validate_request(self, request: ChatCompletionRequest) -> ChatCompletionRequest[UATS]:
54
+ """
55
+ Validates the request
56
+ """
57
+
58
+ if self._mode == ValidationMode.serving:
59
+ if request.model is None:
60
+ raise InvalidRequestException("Model name parameter is required for serving mode")
61
+
62
+ # Validate the messages
63
+ self.validate_messages(request.messages)
64
+
65
+ # Validate the tools
66
+ self._validate_tools(request.tools or [])
67
+
68
+ return request
69
+
70
+ def _validate_function(self, function: Function) -> None:
71
+ """
72
+ Checks:
73
+ - That the function schema is valid
74
+ """
75
+ try:
76
+ Draft7Validator.check_schema(function.parameters)
77
+ except SchemaError as e:
78
+ raise InvalidToolSchemaException(f"Invalid tool schema: {e.message}")
79
+
80
+ if not re.match(r"^[a-zA-Z0-9_-]{1,64}$", function.name):
81
+ raise InvalidToolException(
82
+ f"Function name was {function.name} but must be a-z, A-Z, 0-9, "
83
+ "or contain underscores and dashes, with a maximum length of 64."
84
+ )
85
+
86
+ def _validate_tools(self, tools: List[Tool]) -> None:
87
+ """
88
+ Checks:
89
+ - That the tool schemas are valid
90
+ """
91
+
92
+ for tool in tools:
93
+ self._validate_function(tool.function)
94
+
95
+ def _validate_user_message(self, message: UserMessageType) -> None:
96
+ pass
97
+
98
+ def _validate_tool_message(self, message: ToolMessageType) -> None:
99
+ """
100
+ Checks:
101
+ - The tool name is valid
102
+ """
103
+ if message.name is not None:
104
+ if not re.match(r"^[a-zA-Z0-9_-]{1,64}$", message.name):
105
+ raise InvalidToolMessageException(
106
+ f"Function name was {message.name} but must be a-z, A-Z, 0-9, "
107
+ "or contain underscores and dashes, with a maximum length of 64."
108
+ )
109
+
110
+ def _validate_system_message(self, message: SystemMessageType) -> None:
111
+ """
112
+ Checks:
113
+ - That the system prompt has content
114
+ """
115
+ if message.content is None:
116
+ raise InvalidSystemPromptException("System prompt must have content")
117
+
118
+ def _validate_function_call(self, function_call: FunctionCall) -> None:
119
+ """
120
+ Checks:
121
+ - That the function call has a valid name
122
+ """
123
+ if not re.match(r"^[a-zA-Z0-9_-]{1,64}$", function_call.name):
124
+ raise InvalidFunctionCallException(
125
+ f"Function name was {function_call.name} but must be a-z, A-Z, 0-9, "
126
+ "or contain underscores and dashes, with a maximum length of 64."
127
+ )
128
+
129
+ def _validate_tool_call(self, tool_call: ToolCall, is_last_message: bool) -> None:
130
+ """
131
+ Checks:
132
+ - That the tool call has a valid function
133
+ """
134
+
135
+ self._validate_function_call(tool_call.function)
136
+
137
+ def _validate_assistant_message(self, message: AssistantMessageType, is_last_message: bool = False) -> None:
138
+ """
139
+ Checks:
140
+ - That the assistant message has either text or tool_calls, but not both
141
+ - That the tool calls are valid
142
+ """
143
+
144
+ # Validate that the message has either text or tool_calls
145
+ # but not both and not neither.
146
+ if bool(message.content) == bool(message.tool_calls):
147
+ raise InvalidAssistantMessageException(
148
+ "Assistant message must have either content or tool_calls, but not both."
149
+ )
150
+
151
+ # If we have tool calls, validate them
152
+ if message.tool_calls is not None:
153
+ # Validate that the tool calls are valid
154
+ for tool_call in message.tool_calls:
155
+ self._validate_tool_call(tool_call, is_last_message=is_last_message)
156
+
157
+ if self._mode == ValidationMode.finetuning and isinstance(message, FinetuningAssistantMessage):
158
+ if message.weight is not None and message.weight not in [0, 1]:
159
+ raise InvalidAssistantMessageException("Assistant message weight must be either 0 or 1")
160
+
161
+ if message.prefix:
162
+ if not is_last_message:
163
+ raise InvalidAssistantMessageException("Assistant message with prefix True must be last message")
164
+ # note : we already validate that assistant messsage has content 3 lines up.
165
+
166
+ def _validate_tool_calls_followed_by_tool_messages(self, messages: List[UATS]) -> None:
167
+ """
168
+ Checks:
169
+ - That the number of tool calls and tool messages are the same
170
+ - That the tool calls are followed by tool messages
171
+ """
172
+ prev_role = None
173
+ expected_tool_messages = 0
174
+ for message in messages:
175
+ if prev_role is None:
176
+ prev_role = message.role
177
+ continue
178
+
179
+ if message.role == Roles.tool:
180
+ expected_tool_messages -= 1
181
+ elif message.role == Roles.assistant:
182
+ # if we have an assistant message and we have not received all the function calls
183
+ # we need to raise an exception
184
+ if expected_tool_messages != 0:
185
+ raise InvalidMessageStructureException("Not the same number of function calls and responses")
186
+
187
+ if message.tool_calls is not None:
188
+ # Validate that the number of function calls and responses are the same
189
+ expected_tool_messages = len(message.tool_calls)
190
+
191
+ prev_role = message.role
192
+
193
+ if expected_tool_messages != 0 and self._mode == ValidationMode.serving:
194
+ raise InvalidMessageStructureException("Not the same number of function calls and responses")
195
+ elif expected_tool_messages < 0 and self._mode == ValidationMode.finetuning:
196
+ raise InvalidMessageStructureException("More tool responses than tool calls")
197
+
198
+ def _validate_message_order(self, messages: List[UATS]) -> None:
199
+ """
200
+ Validates the order of the messages, for example user -> assistant -> user -> assistant -> ...
201
+ """
202
+ previous_role = None
203
+ for message in messages:
204
+ current_role = message.role
205
+
206
+ if previous_role is not None:
207
+ if previous_role == Roles.system:
208
+ expected_roles = {Roles.user, Roles.assistant, Roles.system}
209
+ elif previous_role == Roles.user:
210
+ expected_roles = {Roles.assistant, Roles.system, Roles.user}
211
+ elif previous_role == Roles.assistant:
212
+ expected_roles = {Roles.assistant, Roles.user, Roles.tool}
213
+ elif previous_role == Roles.tool:
214
+ expected_roles = {Roles.assistant, Roles.tool}
215
+
216
+ if current_role not in expected_roles:
217
+ raise InvalidMessageStructureException(
218
+ f"Unexpected role '{current_role}' after role '{previous_role}'"
219
+ )
220
+
221
+ previous_role = current_role
222
+
223
+ def _validate_last_message(self, message: UATS) -> None:
224
+ # The last message must be a user or tool message in serving mode or an assistant message in finetuning mode
225
+ last_message_role = message.role
226
+ if self._mode == ValidationMode.finetuning:
227
+ if last_message_role != Roles.assistant:
228
+ raise InvalidMessageStructureException(
229
+ f"Expected last role Assistant for finetuning but got {last_message_role}"
230
+ )
231
+ else:
232
+ bad_assistant = isinstance(message, AssistantMessage) and not message.prefix
233
+ bad_role = message.role not in {Roles.user, Roles.tool}
234
+ if bad_assistant and bad_role:
235
+ raise InvalidMessageStructureException(
236
+ f"Expected last role User or Tool (or Assistant with prefix True) for serving"
237
+ f" but got {last_message_role}"
238
+ )
239
+
240
+ def _validate_message_list_structure(self, messages: List[UATS]) -> None:
241
+ """
242
+ Validates the structure of the list of messages
243
+
244
+ For example the messages must be in the correct order of user/assistant/tool
245
+ """
246
+
247
+ if len(messages) == 0:
248
+ raise InvalidMessageStructureException("Conversation must have at least one message")
249
+
250
+ # If we have one message it must be a user or a system message
251
+ if len(messages) == 1:
252
+ if messages[0].role not in {Roles.user, Roles.system}:
253
+ raise InvalidMessageStructureException("Conversation must start with a user message or system message")
254
+
255
+ # Always check the last message if in fine-tuning mode
256
+ if self._mode == ValidationMode.finetuning or len(messages) > 1:
257
+ self._validate_last_message(messages[-1])
258
+
259
+ self._validate_message_order(messages)
260
+ self._validate_tool_calls_followed_by_tool_messages(messages)
261
+
262
+ def _validate_message_list_content(self, messages: List[UATS]) -> None:
263
+ """
264
+ Validates the content of the messages
265
+ """
266
+
267
+ for idx, message in enumerate(messages):
268
+ if message.role == Roles.user:
269
+ self._validate_user_message(message)
270
+ elif message.role == Roles.assistant:
271
+ self._validate_assistant_message(message, is_last_message=idx == len(messages) - 1)
272
+ elif message.role == Roles.tool:
273
+ self._validate_tool_message(message)
274
+ elif message.role == Roles.system:
275
+ self._validate_system_message(message)
276
+ else:
277
+ raise InvalidRequestException(f"Unsupported message type {type(message)}")
278
+
279
+
280
+ class MistralRequestValidatorV3(MistralRequestValidator):
281
+ def _validate_tool_message(self, message: ToolMessageType) -> None:
282
+ """
283
+ Checks:
284
+ - The tool name is valid
285
+ - Tool call id is valid
286
+ """
287
+ if message.name is not None:
288
+ if not re.match(r"^[a-zA-Z0-9_-]{1,64}$", message.name):
289
+ raise InvalidToolMessageException(
290
+ f"Function name was {message.name} but must be a-z, A-Z, 0-9, "
291
+ "or contain underscores and dashes, with a maximum length of 64."
292
+ )
293
+
294
+ if message.tool_call_id is None:
295
+ raise InvalidRequestException("Tool call id has to be defined.")
296
+
297
+ if not re.match(r"^[a-zA-Z0-9]{9}$", message.tool_call_id):
298
+ raise InvalidToolMessageException(
299
+ f"Tool call id was {message.tool_call_id} but must be a-z, A-Z, 0-9, with a length of 9."
300
+ )
301
+
302
+ def _validate_tool_call(self, tool_call: ToolCall, is_last_message: bool) -> None:
303
+ """
304
+ Validate that the tool call has a valid ID
305
+ """
306
+ if tool_call.id != "null":
307
+ if not re.match(r"^[a-zA-Z0-9]{9}$", tool_call.id):
308
+ raise InvalidFunctionCallException(
309
+ f"Tool call id was {tool_call.id} but must be a-z, A-Z, 0-9, with a length of 9."
310
+ )
311
+ if self._mode == ValidationMode.finetuning and not is_last_message and tool_call.id == "null":
312
+ err_message = "Tool call id of assistant message that is not last has to be defined in finetuning mode."
313
+ raise InvalidFunctionCallException(err_message)
314
+
315
+ if self._mode == ValidationMode.serving and tool_call.id == "null":
316
+ raise InvalidFunctionCallException("Tool call id has to be defined in serving mode.")
317
+
318
+ self._validate_function_call(tool_call.function)
319
+
320
+ def _validate_last_message(self, message: UATS) -> None:
321
+ super()._validate_last_message(message)
322
+
323
+ if self._mode == ValidationMode.finetuning:
324
+ # in finetuning mode it has to be an assistant message
325
+ # as checked by parent `_validate_last_message`
326
+ if message.tool_calls is not None:
327
+ for tool_call in message.tool_calls:
328
+ self._validate_tool_call(tool_call, is_last_message=True)
.venv/lib/python3.11/site-packages/mistral_common/protocol/utils.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ import uuid
2
+
3
+
4
+ def random_uuid() -> str:
5
+ return str(uuid.uuid4().hex)
.venv/lib/python3.11/site-packages/mistral_common/py.typed ADDED
File without changes
.venv/lib/python3.11/site-packages/numpy/polynomial/tests/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (195 Bytes). View file
 
.venv/lib/python3.11/site-packages/numpy/polynomial/tests/__pycache__/test_hermite_e.cpython-311.pyc ADDED
Binary file (38.6 kB). View file
 
.venv/lib/python3.11/site-packages/vllm-0.7.2.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
.venv/lib/python3.11/site-packages/vllm-0.7.2.dist-info/LICENSE ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
.venv/lib/python3.11/site-packages/vllm-0.7.2.dist-info/METADATA ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.2
2
+ Name: vllm
3
+ Version: 0.7.2
4
+ Summary: A high-throughput and memory-efficient inference and serving engine for LLMs
5
+ Home-page: https://github.com/vllm-project/vllm
6
+ Author: vLLM Team
7
+ License: Apache 2.0
8
+ Project-URL: Homepage, https://github.com/vllm-project/vllm
9
+ Project-URL: Documentation, https://vllm.readthedocs.io/en/latest/
10
+ Classifier: Programming Language :: Python :: 3.9
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: License :: OSI Approved :: Apache Software License
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: Information Technology
17
+ Classifier: Intended Audience :: Science/Research
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
20
+ Requires-Python: >=3.9
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: psutil
24
+ Requires-Dist: sentencepiece
25
+ Requires-Dist: numpy<2.0.0
26
+ Requires-Dist: requests>=2.26.0
27
+ Requires-Dist: tqdm
28
+ Requires-Dist: blake3
29
+ Requires-Dist: py-cpuinfo
30
+ Requires-Dist: transformers>=4.48.2
31
+ Requires-Dist: tokenizers>=0.19.1
32
+ Requires-Dist: protobuf
33
+ Requires-Dist: fastapi<0.113.0,>=0.107.0; python_version < "3.9"
34
+ Requires-Dist: fastapi!=0.113.*,!=0.114.0,>=0.107.0; python_version >= "3.9"
35
+ Requires-Dist: aiohttp
36
+ Requires-Dist: openai>=1.52.0
37
+ Requires-Dist: uvicorn[standard]
38
+ Requires-Dist: pydantic>=2.9
39
+ Requires-Dist: prometheus_client>=0.18.0
40
+ Requires-Dist: pillow
41
+ Requires-Dist: prometheus-fastapi-instrumentator>=7.0.0
42
+ Requires-Dist: tiktoken>=0.6.0
43
+ Requires-Dist: lm-format-enforcer<0.11,>=0.10.9
44
+ Requires-Dist: outlines==0.1.11
45
+ Requires-Dist: lark==1.2.2
46
+ Requires-Dist: xgrammar>=0.1.6; platform_machine == "x86_64"
47
+ Requires-Dist: typing_extensions>=4.10
48
+ Requires-Dist: filelock>=3.16.1
49
+ Requires-Dist: partial-json-parser
50
+ Requires-Dist: pyzmq
51
+ Requires-Dist: msgspec
52
+ Requires-Dist: gguf==0.10.0
53
+ Requires-Dist: importlib_metadata
54
+ Requires-Dist: mistral_common[opencv]>=1.5.0
55
+ Requires-Dist: pyyaml
56
+ Requires-Dist: six>=1.16.0; python_version > "3.11"
57
+ Requires-Dist: setuptools>=74.1.1; python_version > "3.11"
58
+ Requires-Dist: einops
59
+ Requires-Dist: compressed-tensors==0.9.1
60
+ Requires-Dist: depyf==0.18.0
61
+ Requires-Dist: cloudpickle
62
+ Requires-Dist: ray[default]>=2.9
63
+ Requires-Dist: nvidia-ml-py>=12.560.30
64
+ Requires-Dist: torch==2.5.1
65
+ Requires-Dist: torchaudio==2.5.1
66
+ Requires-Dist: torchvision==0.20.1
67
+ Requires-Dist: xformers==0.0.28.post3; platform_system == "Linux" and platform_machine == "x86_64"
68
+ Provides-Extra: tensorizer
69
+ Requires-Dist: tensorizer>=2.9.0; extra == "tensorizer"
70
+ Provides-Extra: runai
71
+ Requires-Dist: runai-model-streamer; extra == "runai"
72
+ Requires-Dist: runai-model-streamer-s3; extra == "runai"
73
+ Requires-Dist: boto3; extra == "runai"
74
+ Provides-Extra: audio
75
+ Requires-Dist: librosa; extra == "audio"
76
+ Requires-Dist: soundfile; extra == "audio"
77
+ Provides-Extra: video
78
+ Requires-Dist: decord; extra == "video"
79
+ Dynamic: author
80
+ Dynamic: classifier
81
+ Dynamic: description
82
+ Dynamic: description-content-type
83
+ Dynamic: home-page
84
+ Dynamic: license
85
+ Dynamic: project-url
86
+ Dynamic: provides-extra
87
+ Dynamic: requires-dist
88
+ Dynamic: requires-python
89
+ Dynamic: summary
90
+
91
+ <p align="center">
92
+ <picture>
93
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/vllm-project/vllm/main/docs/source/assets/logos/vllm-logo-text-dark.png">
94
+ <img alt="vLLM" src="https://raw.githubusercontent.com/vllm-project/vllm/main/docs/source/assets/logos/vllm-logo-text-light.png" width=55%>
95
+ </picture>
96
+ </p>
97
+
98
+ <h3 align="center">
99
+ Easy, fast, and cheap LLM serving for everyone
100
+ </h3>
101
+
102
+ <p align="center">
103
+ | <a href="https://docs.vllm.ai"><b>Documentation</b></a> | <a href="https://vllm.ai"><b>Blog</b></a> | <a href="https://arxiv.org/abs/2309.06180"><b>Paper</b></a> | <a href="https://x.com/vllm_project"><b>Twitter/X</b></a> | <a href="https://slack.vllm.ai"><b>Developer Slack</b></a> |
104
+ </p>
105
+
106
+ ---
107
+
108
+ *Latest News* 🔥
109
+ - [2025/01] We are excited to announce the alpha release of vLLM V1: A major architectural upgrade with 1.7x speedup! Clean code, optimized execution loop, zero-overhead prefix caching, enhanced multimodal support, and more. Please check out our blog post [here](https://blog.vllm.ai/2025/01/27/v1-alpha-release.html).
110
+ - [2025/01] We hosted [the eighth vLLM meetup](https://lu.ma/zep56hui) with Google Cloud! Please find the meetup slides from vLLM team [here](https://docs.google.com/presentation/d/1epVkt4Zu8Jz_S5OhEHPc798emsYh2BwYfRuDDVEF7u4/edit?usp=sharing).
111
+ - [2024/12] vLLM joins [pytorch ecosystem](https://pytorch.org/blog/vllm-joins-pytorch)! Easy, Fast, and Cheap LLM Serving for Everyone!
112
+ - [2024/11] We hosted [the seventh vLLM meetup](https://lu.ma/h0qvrajz) with Snowflake! Please find the meetup slides from vLLM team [here](https://docs.google.com/presentation/d/1e3CxQBV3JsfGp30SwyvS3eM_tW-ghOhJ9PAJGK6KR54/edit?usp=sharing), and Snowflake team [here](https://docs.google.com/presentation/d/1qF3RkDAbOULwz9WK5TOltt2fE9t6uIc_hVNLFAaQX6A/edit?usp=sharing).
113
+ - [2024/10] We have just created a developer slack ([slack.vllm.ai](https://slack.vllm.ai)) focusing on coordinating contributions and discussing features. Please feel free to join us there!
114
+ - [2024/10] Ray Summit 2024 held a special track for vLLM! Please find the opening talk slides from the vLLM team [here](https://docs.google.com/presentation/d/1B_KQxpHBTRa_mDF-tR6i8rWdOU5QoTZNcEg2MKZxEHM/edit?usp=sharing). Learn more from the [talks](https://www.youtube.com/playlist?list=PLzTswPQNepXl6AQwifuwUImLPFRVpksjR) from other vLLM contributors and users!
115
+ - [2024/09] We hosted [the sixth vLLM meetup](https://lu.ma/87q3nvnh) with NVIDIA! Please find the meetup slides [here](https://docs.google.com/presentation/d/1wrLGwytQfaOTd5wCGSPNhoaW3nq0E-9wqyP7ny93xRs/edit?usp=sharing).
116
+ - [2024/07] We hosted [the fifth vLLM meetup](https://lu.ma/lp0gyjqr) with AWS! Please find the meetup slides [here](https://docs.google.com/presentation/d/1RgUD8aCfcHocghoP3zmXzck9vX3RCI9yfUAB2Bbcl4Y/edit?usp=sharing).
117
+ - [2024/07] In partnership with Meta, vLLM officially supports Llama 3.1 with FP8 quantization and pipeline parallelism! Please check out our blog post [here](https://blog.vllm.ai/2024/07/23/llama31.html).
118
+ - [2024/06] We hosted [the fourth vLLM meetup](https://lu.ma/agivllm) with Cloudflare and BentoML! Please find the meetup slides [here](https://docs.google.com/presentation/d/1iJ8o7V2bQEi0BFEljLTwc5G1S10_Rhv3beed5oB0NJ4/edit?usp=sharing).
119
+ - [2024/04] We hosted [the third vLLM meetup](https://robloxandvllmmeetup2024.splashthat.com/) with Roblox! Please find the meetup slides [here](https://docs.google.com/presentation/d/1A--47JAK4BJ39t954HyTkvtfwn0fkqtsL8NGFuslReM/edit?usp=sharing).
120
+ - [2024/01] We hosted [the second vLLM meetup](https://lu.ma/ygxbpzhl) with IBM! Please find the meetup slides [here](https://docs.google.com/presentation/d/12mI2sKABnUw5RBWXDYY-HtHth4iMSNcEoQ10jDQbxgA/edit?usp=sharing).
121
+ - [2023/10] We hosted [the first vLLM meetup](https://lu.ma/first-vllm-meetup) with a16z! Please find the meetup slides [here](https://docs.google.com/presentation/d/1QL-XPFXiFpDBh86DbEegFXBXFXjix4v032GhShbKf3s/edit?usp=sharing).
122
+ - [2023/08] We would like to express our sincere gratitude to [Andreessen Horowitz](https://a16z.com/2023/08/30/supporting-the-open-source-ai-community/) (a16z) for providing a generous grant to support the open-source development and research of vLLM.
123
+ - [2023/06] We officially released vLLM! FastChat-vLLM integration has powered [LMSYS Vicuna and Chatbot Arena](https://chat.lmsys.org) since mid-April. Check out our [blog post](https://vllm.ai).
124
+
125
+ ---
126
+ ## About
127
+ vLLM is a fast and easy-to-use library for LLM inference and serving.
128
+
129
+ Originally developed in the [Sky Computing Lab](https://sky.cs.berkeley.edu) at UC Berkeley, vLLM has evolved into a community-driven project with contributions from both academia and industry.
130
+
131
+ vLLM is fast with:
132
+
133
+ - State-of-the-art serving throughput
134
+ - Efficient management of attention key and value memory with [**PagedAttention**](https://blog.vllm.ai/2023/06/20/vllm.html)
135
+ - Continuous batching of incoming requests
136
+ - Fast model execution with CUDA/HIP graph
137
+ - Quantizations: [GPTQ](https://arxiv.org/abs/2210.17323), [AWQ](https://arxiv.org/abs/2306.00978), INT4, INT8, and FP8.
138
+ - Optimized CUDA kernels, including integration with FlashAttention and FlashInfer.
139
+ - Speculative decoding
140
+ - Chunked prefill
141
+
142
+ **Performance benchmark**: We include a performance benchmark at the end of [our blog post](https://blog.vllm.ai/2024/09/05/perf-update.html). It compares the performance of vLLM against other LLM serving engines ([TensorRT-LLM](https://github.com/NVIDIA/TensorRT-LLM), [SGLang](https://github.com/sgl-project/sglang) and [LMDeploy](https://github.com/InternLM/lmdeploy)). The implementation is under [nightly-benchmarks folder](.buildkite/nightly-benchmarks/) and you can [reproduce](https://github.com/vllm-project/vllm/issues/8176) this benchmark using our one-click runnable script.
143
+
144
+ vLLM is flexible and easy to use with:
145
+
146
+ - Seamless integration with popular Hugging Face models
147
+ - High-throughput serving with various decoding algorithms, including *parallel sampling*, *beam search*, and more
148
+ - Tensor parallelism and pipeline parallelism support for distributed inference
149
+ - Streaming outputs
150
+ - OpenAI-compatible API server
151
+ - Support NVIDIA GPUs, AMD CPUs and GPUs, Intel CPUs and GPUs, PowerPC CPUs, TPU, and AWS Neuron.
152
+ - Prefix caching support
153
+ - Multi-lora support
154
+
155
+ vLLM seamlessly supports most popular open-source models on HuggingFace, including:
156
+ - Transformer-like LLMs (e.g., Llama)
157
+ - Mixture-of-Expert LLMs (e.g., Mixtral, Deepseek-V2 and V3)
158
+ - Embedding Models (e.g. E5-Mistral)
159
+ - Multi-modal LLMs (e.g., LLaVA)
160
+
161
+ Find the full list of supported models [here](https://docs.vllm.ai/en/latest/models/supported_models.html).
162
+
163
+ ## Getting Started
164
+
165
+ Install vLLM with `pip` or [from source](https://docs.vllm.ai/en/latest/getting_started/installation/gpu/index.html#build-wheel-from-source):
166
+
167
+ ```bash
168
+ pip install vllm
169
+ ```
170
+
171
+ Visit our [documentation](https://docs.vllm.ai/en/latest/) to learn more.
172
+ - [Installation](https://docs.vllm.ai/en/latest/getting_started/installation/index.html)
173
+ - [Quickstart](https://docs.vllm.ai/en/latest/getting_started/quickstart.html)
174
+ - [List of Supported Models](https://docs.vllm.ai/en/latest/models/supported_models.html)
175
+
176
+ ## Contributing
177
+
178
+ We welcome and value any contributions and collaborations.
179
+ Please check out [CONTRIBUTING.md](./CONTRIBUTING.md) for how to get involved.
180
+
181
+ ## Sponsors
182
+
183
+ vLLM is a community project. Our compute resources for development and testing are supported by the following organizations. Thank you for your support!
184
+
185
+ <!-- Note: Please sort them in alphabetical order. -->
186
+ <!-- Note: Please keep these consistent with docs/source/community/sponsors.md -->
187
+ Cash Donations:
188
+ - a16z
189
+ - Dropbox
190
+ - Sequoia Capital
191
+ - Skywork AI
192
+ - ZhenFund
193
+
194
+ Compute Resources:
195
+ - AMD
196
+ - Anyscale
197
+ - AWS
198
+ - Crusoe Cloud
199
+ - Databricks
200
+ - DeepInfra
201
+ - Google Cloud
202
+ - Lambda Lab
203
+ - Nebius
204
+ - Novita AI
205
+ - NVIDIA
206
+ - Replicate
207
+ - Roblox
208
+ - RunPod
209
+ - Trainy
210
+ - UC Berkeley
211
+ - UC San Diego
212
+
213
+ Slack Sponsor: Anyscale
214
+
215
+ We also have an official fundraising venue through [OpenCollective](https://opencollective.com/vllm). We plan to use the fund to support the development, maintenance, and adoption of vLLM.
216
+
217
+ ## Citation
218
+
219
+ If you use vLLM for your research, please cite our [paper](https://arxiv.org/abs/2309.06180):
220
+ ```bibtex
221
+ @inproceedings{kwon2023efficient,
222
+ title={Efficient Memory Management for Large Language Model Serving with PagedAttention},
223
+ author={Woosuk Kwon and Zhuohan Li and Siyuan Zhuang and Ying Sheng and Lianmin Zheng and Cody Hao Yu and Joseph E. Gonzalez and Hao Zhang and Ion Stoica},
224
+ booktitle={Proceedings of the ACM SIGOPS 29th Symposium on Operating Systems Principles},
225
+ year={2023}
226
+ }
227
+ ```
228
+
229
+ ## Contact Us
230
+
231
+ * For technical questions and feature requests, please use Github issues or discussions.
232
+ * For discussing with fellow users and coordinating contributions and development, please use Slack.
233
+ * For security disclosures, please use Github's security advisory feature.
234
+ * For collaborations and partnerships, please contact us at vllm-questions AT lists.berkeley.edu.
235
+
236
+ ## Media Kit
237
+
238
+ * If you wish to use vLLM's logo, please refer to [our media kit repo](https://github.com/vllm-project/media-kit).
.venv/lib/python3.11/site-packages/vllm-0.7.2.dist-info/RECORD ADDED
The diff for this file is too large to render. See raw diff
 
.venv/lib/python3.11/site-packages/vllm-0.7.2.dist-info/REQUESTED ADDED
File without changes
.venv/lib/python3.11/site-packages/vllm-0.7.2.dist-info/WHEEL ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (75.8.0)
3
+ Root-Is-Purelib: false
4
+ Tag: cp38-abi3-linux_x86_64
5
+
.venv/lib/python3.11/site-packages/vllm-0.7.2.dist-info/entry_points.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ [console_scripts]
2
+ vllm = vllm.scripts:main
.venv/lib/python3.11/site-packages/vllm-0.7.2.dist-info/top_level.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ vllm
.venv/lib/python3.11/site-packages/xgrammar/__init__.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from . import testing
2
+ from .compiler import CompiledGrammar, GrammarCompiler
3
+ from .contrib import hf
4
+ from .grammar import Grammar, StructuralTagItem
5
+ from .matcher import (
6
+ GrammarMatcher,
7
+ allocate_token_bitmask,
8
+ apply_token_bitmask_inplace,
9
+ bitmask_dtype,
10
+ get_bitmask_shape,
11
+ reset_token_bitmask,
12
+ )
13
+ from .tokenizer_info import TokenizerInfo, VocabType
.venv/lib/python3.11/site-packages/xgrammar/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (835 Bytes). View file
 
.venv/lib/python3.11/site-packages/xgrammar/__pycache__/base.cpython-311.pyc ADDED
Binary file (3.43 kB). View file
 
.venv/lib/python3.11/site-packages/xgrammar/__pycache__/compiler.cpython-311.pyc ADDED
Binary file (9.18 kB). View file
 
.venv/lib/python3.11/site-packages/xgrammar/__pycache__/grammar.cpython-311.pyc ADDED
Binary file (14.4 kB). View file