crit-core 0.10.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- crit_core/__init__.py +2 -0
- crit_core/constraints/__init__.py +15 -0
- crit_core/constraints/choices.py +83 -0
- crit_core/constraints/compiler.py +722 -0
- crit_core/constraints/grammar.py +171 -0
- crit_core/constraints/preparation.py +275 -0
- crit_core/constraints/vocabulary.py +118 -0
- crit_core/files.py +239 -0
- crit_core/jsonfile.py +167 -0
- crit_core/machine.py +231 -0
- crit_core/model/__init__.py +28 -0
- crit_core/model/config.py +869 -0
- crit_core/model/config_keys.json +11 -0
- crit_core/model/drafters.py +193 -0
- crit_core/model/gguf.py +530 -0
- crit_core/model/gguf_deepseek4.py +142 -0
- crit_core/model/gguf_files.py +515 -0
- crit_core/model/gguf_qwen4exp.py +216 -0
- crit_core/model/onnx.py +356 -0
- crit_core/model/safetensors.py +561 -0
- crit_core/model/source.py +281 -0
- crit_core/model/torch_pickle.py +296 -0
- crit_core/native.py +496 -0
- crit_core/serving.py +840 -0
- crit_core/text/__init__.py +40 -0
- crit_core/text/detokenize.py +263 -0
- crit_core/text/errors.py +84 -0
- crit_core/text/generation.py +214 -0
- crit_core/text/markers.py +137 -0
- crit_core/text/messages.py +113 -0
- crit_core/text/model.py +127 -0
- crit_core/text/reasoning.py +132 -0
- crit_core/text/stops.py +156 -0
- crit_core/text/stream.py +97 -0
- crit_core/text/template.py +453 -0
- crit_core/text/templates/deepseek-v4.jinja +250 -0
- crit_core/text/tokenizer.py +248 -0
- crit_core/text/tools.py +618 -0
- crit_core-0.10.0.dist-info/METADATA +11 -0
- crit_core-0.10.0.dist-info/RECORD +43 -0
- crit_core-0.10.0.dist-info/WHEEL +5 -0
- crit_core-0.10.0.dist-info/licenses/LICENSE +208 -0
- crit_core-0.10.0.dist-info/top_level.txt +1 -0
crit_core/__init__.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Structured output: constraint languages, their compiler and preparation, and the tokenizer byte table.
|
|
2
|
+
|
|
3
|
+
Standard library only (a `crit_core.text.Tokenizer` is passed in, never imported here). The native matchers that
|
|
4
|
+
mask tokens during generation are in crit/constraints.h; see core/src/constraints/README.md.
|
|
5
|
+
"""
|
|
6
|
+
from .compiler import (VERSION, CompileRequest, CompiledConstraint, CompilerCache, UnsupportedConstraint,
|
|
7
|
+
compile_language, make_compile_request)
|
|
8
|
+
from .grammar import ByteGrammar, GrammarError, GrammarState, json_object_matches, matches
|
|
9
|
+
from .preparation import Preparation, PreparationFailed, PreparationPending, PreparationService, PreparedMatcher
|
|
10
|
+
from .vocabulary import ByteVocabulary, byte_vocabulary, from_pieces
|
|
11
|
+
|
|
12
|
+
__all__ = ["VERSION", "ByteGrammar", "ByteVocabulary", "CompileRequest", "CompiledConstraint", "CompilerCache",
|
|
13
|
+
"GrammarError", "GrammarState", "Preparation", "PreparationFailed", "PreparationPending",
|
|
14
|
+
"PreparationService", "PreparedMatcher", "UnsupportedConstraint", "byte_vocabulary", "compile_language",
|
|
15
|
+
"from_pieces", "json_object_matches", "make_compile_request", "matches"]
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"""Python reference for finite byte choices (the native ChoiceMatcher); mutable state is private to one request."""
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@dataclass(frozen=True, init=False)
|
|
6
|
+
class ChoiceGrammar:
|
|
7
|
+
_nodes: tuple
|
|
8
|
+
_terminal: frozenset
|
|
9
|
+
vocabulary: tuple
|
|
10
|
+
eos: int
|
|
11
|
+
|
|
12
|
+
def __init__(self, choices, vocabulary, eos):
|
|
13
|
+
choices, vocabulary = tuple(choices), tuple(vocabulary)
|
|
14
|
+
if (not choices or len(choices) > 65536 or not vocabulary or len(vocabulary) > 1048576
|
|
15
|
+
or any(type(x) is not bytes for x in choices + vocabulary)
|
|
16
|
+
or type(eos) is not int or not 0 <= eos < len(vocabulary)
|
|
17
|
+
or vocabulary[eos] or sum(map(len, choices)) > 1048576
|
|
18
|
+
or sum(map(len, vocabulary)) > 67108864):
|
|
19
|
+
raise ValueError("bounded byte choices/vocabulary and an empty EOS entry required")
|
|
20
|
+
nodes, terminal = [{}], set()
|
|
21
|
+
for choice in choices:
|
|
22
|
+
node = 0
|
|
23
|
+
for byte in choice:
|
|
24
|
+
if byte not in nodes[node]:
|
|
25
|
+
nodes[node][byte] = len(nodes)
|
|
26
|
+
nodes.append({})
|
|
27
|
+
node = nodes[node][byte]
|
|
28
|
+
terminal.add(node)
|
|
29
|
+
# Freeze all exposed inputs; states never mutate the compiled language.
|
|
30
|
+
object.__setattr__(self, "_nodes", tuple(tuple(sorted(node.items())) for node in nodes))
|
|
31
|
+
object.__setattr__(self, "_terminal", frozenset(terminal))
|
|
32
|
+
object.__setattr__(self, "vocabulary", vocabulary)
|
|
33
|
+
object.__setattr__(self, "eos", eos)
|
|
34
|
+
|
|
35
|
+
def transition(self, node, token):
|
|
36
|
+
if type(token) is not int or not 0 <= token < len(self.vocabulary):
|
|
37
|
+
raise ValueError("token outside vocabulary")
|
|
38
|
+
if token == self.eos:
|
|
39
|
+
return -1 if node in self._terminal else None
|
|
40
|
+
piece = self.vocabulary[token]
|
|
41
|
+
if not piece or node == -1:
|
|
42
|
+
return None
|
|
43
|
+
for byte in piece:
|
|
44
|
+
node = dict(self._nodes[node]).get(byte)
|
|
45
|
+
if node is None:
|
|
46
|
+
return None
|
|
47
|
+
return node
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class ChoiceState:
|
|
51
|
+
def __init__(self, grammar):
|
|
52
|
+
if not isinstance(grammar, ChoiceGrammar):
|
|
53
|
+
raise ValueError("compiled choice grammar required")
|
|
54
|
+
self.grammar, self._states = grammar, [0]
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def ended(self):
|
|
58
|
+
return self._states[-1] == -1
|
|
59
|
+
|
|
60
|
+
def fork(self):
|
|
61
|
+
result = ChoiceState(self.grammar)
|
|
62
|
+
result._states = self._states.copy()
|
|
63
|
+
return result
|
|
64
|
+
|
|
65
|
+
def allowed(self):
|
|
66
|
+
if self.ended:
|
|
67
|
+
return (self.grammar.eos,) # absorbing next law for terminal verification rows
|
|
68
|
+
result = tuple(i for i in range(len(self.grammar.vocabulary))
|
|
69
|
+
if self.grammar.transition(self._states[-1], i) is not None)
|
|
70
|
+
if not result:
|
|
71
|
+
raise ValueError("choice language is unreachable with this vocabulary")
|
|
72
|
+
return result
|
|
73
|
+
|
|
74
|
+
def append(self, token):
|
|
75
|
+
node = self.grammar.transition(self._states[-1], token)
|
|
76
|
+
if node is None:
|
|
77
|
+
raise ValueError("token violates choice language")
|
|
78
|
+
self._states.append(node)
|
|
79
|
+
|
|
80
|
+
def rewind(self, count):
|
|
81
|
+
if type(count) is not int or not 0 <= count < len(self._states):
|
|
82
|
+
raise ValueError("rewind cannot extend output")
|
|
83
|
+
del self._states[count + 1:]
|