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.
Files changed (43) hide show
  1. crit_core/__init__.py +2 -0
  2. crit_core/constraints/__init__.py +15 -0
  3. crit_core/constraints/choices.py +83 -0
  4. crit_core/constraints/compiler.py +722 -0
  5. crit_core/constraints/grammar.py +171 -0
  6. crit_core/constraints/preparation.py +275 -0
  7. crit_core/constraints/vocabulary.py +118 -0
  8. crit_core/files.py +239 -0
  9. crit_core/jsonfile.py +167 -0
  10. crit_core/machine.py +231 -0
  11. crit_core/model/__init__.py +28 -0
  12. crit_core/model/config.py +869 -0
  13. crit_core/model/config_keys.json +11 -0
  14. crit_core/model/drafters.py +193 -0
  15. crit_core/model/gguf.py +530 -0
  16. crit_core/model/gguf_deepseek4.py +142 -0
  17. crit_core/model/gguf_files.py +515 -0
  18. crit_core/model/gguf_qwen4exp.py +216 -0
  19. crit_core/model/onnx.py +356 -0
  20. crit_core/model/safetensors.py +561 -0
  21. crit_core/model/source.py +281 -0
  22. crit_core/model/torch_pickle.py +296 -0
  23. crit_core/native.py +496 -0
  24. crit_core/serving.py +840 -0
  25. crit_core/text/__init__.py +40 -0
  26. crit_core/text/detokenize.py +263 -0
  27. crit_core/text/errors.py +84 -0
  28. crit_core/text/generation.py +214 -0
  29. crit_core/text/markers.py +137 -0
  30. crit_core/text/messages.py +113 -0
  31. crit_core/text/model.py +127 -0
  32. crit_core/text/reasoning.py +132 -0
  33. crit_core/text/stops.py +156 -0
  34. crit_core/text/stream.py +97 -0
  35. crit_core/text/template.py +453 -0
  36. crit_core/text/templates/deepseek-v4.jinja +250 -0
  37. crit_core/text/tokenizer.py +248 -0
  38. crit_core/text/tools.py +618 -0
  39. crit_core-0.10.0.dist-info/METADATA +11 -0
  40. crit_core-0.10.0.dist-info/RECORD +43 -0
  41. crit_core-0.10.0.dist-info/WHEEL +5 -0
  42. crit_core-0.10.0.dist-info/licenses/LICENSE +208 -0
  43. crit_core-0.10.0.dist-info/top_level.txt +1 -0
crit_core/__init__.py ADDED
@@ -0,0 +1,2 @@
1
+ """crit Core for Python: model files, model config and the text layer (tokenizer, chat templates, stops)."""
2
+ __version__ = "0.10.0"
@@ -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:]