cortex-llm 1.0.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 (48) hide show
  1. cortex/__init__.py +73 -0
  2. cortex/__main__.py +83 -0
  3. cortex/config.py +329 -0
  4. cortex/conversation_manager.py +468 -0
  5. cortex/fine_tuning/__init__.py +8 -0
  6. cortex/fine_tuning/dataset.py +332 -0
  7. cortex/fine_tuning/mlx_lora_trainer.py +502 -0
  8. cortex/fine_tuning/trainer.py +957 -0
  9. cortex/fine_tuning/wizard.py +707 -0
  10. cortex/gpu_validator.py +467 -0
  11. cortex/inference_engine.py +727 -0
  12. cortex/metal/__init__.py +275 -0
  13. cortex/metal/gpu_validator.py +177 -0
  14. cortex/metal/memory_pool.py +886 -0
  15. cortex/metal/mlx_accelerator.py +678 -0
  16. cortex/metal/mlx_converter.py +638 -0
  17. cortex/metal/mps_optimizer.py +417 -0
  18. cortex/metal/optimizer.py +665 -0
  19. cortex/metal/performance_profiler.py +364 -0
  20. cortex/model_downloader.py +130 -0
  21. cortex/model_manager.py +2187 -0
  22. cortex/quantization/__init__.py +5 -0
  23. cortex/quantization/dynamic_quantizer.py +736 -0
  24. cortex/template_registry/__init__.py +15 -0
  25. cortex/template_registry/auto_detector.py +144 -0
  26. cortex/template_registry/config_manager.py +234 -0
  27. cortex/template_registry/interactive.py +260 -0
  28. cortex/template_registry/registry.py +347 -0
  29. cortex/template_registry/template_profiles/__init__.py +5 -0
  30. cortex/template_registry/template_profiles/base.py +142 -0
  31. cortex/template_registry/template_profiles/complex/__init__.py +5 -0
  32. cortex/template_registry/template_profiles/complex/reasoning.py +263 -0
  33. cortex/template_registry/template_profiles/standard/__init__.py +9 -0
  34. cortex/template_registry/template_profiles/standard/alpaca.py +73 -0
  35. cortex/template_registry/template_profiles/standard/chatml.py +82 -0
  36. cortex/template_registry/template_profiles/standard/gemma.py +103 -0
  37. cortex/template_registry/template_profiles/standard/llama.py +87 -0
  38. cortex/template_registry/template_profiles/standard/simple.py +65 -0
  39. cortex/ui/__init__.py +120 -0
  40. cortex/ui/cli.py +1685 -0
  41. cortex/ui/markdown_render.py +185 -0
  42. cortex/ui/terminal_app.py +534 -0
  43. cortex_llm-1.0.0.dist-info/METADATA +275 -0
  44. cortex_llm-1.0.0.dist-info/RECORD +48 -0
  45. cortex_llm-1.0.0.dist-info/WHEEL +5 -0
  46. cortex_llm-1.0.0.dist-info/entry_points.txt +2 -0
  47. cortex_llm-1.0.0.dist-info/licenses/LICENSE +21 -0
  48. cortex_llm-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,185 @@
1
+ """Markdown rendering helpers with <think> dimming support."""
2
+
3
+ from typing import List
4
+
5
+ from rich.console import Console
6
+ from rich.markdown import Markdown
7
+ from rich.segment import Segment
8
+ from rich.style import Style
9
+ from rich.syntax import Syntax
10
+
11
+ THINK_START_MARKER = "[[[THINK_START]]]"
12
+ THINK_END_MARKER = "[[[THINK_END]]]"
13
+
14
+
15
+ def _mark_think_sections(text: str) -> str:
16
+ """Replace <think> tags with sentinel markers outside fenced code blocks."""
17
+ lines = text.splitlines(keepends=True)
18
+ in_code_block = False
19
+ output: List[str] = []
20
+
21
+ for line in lines:
22
+ stripped = line.lstrip()
23
+ if stripped.startswith("```"):
24
+ in_code_block = not in_code_block
25
+ output.append(line)
26
+ continue
27
+
28
+ if in_code_block:
29
+ output.append(line)
30
+ continue
31
+
32
+ output.append(
33
+ line.replace("<think>", THINK_START_MARKER).replace("</think>", THINK_END_MARKER)
34
+ )
35
+
36
+ return "".join(output)
37
+
38
+
39
+ class CodeBlockWithLineNumbers(Markdown.elements["fence"]):
40
+ """Markdown code block with line numbers."""
41
+
42
+ def __rich_console__(self, console: Console, options):
43
+ code = str(self.text).rstrip()
44
+ syntax = Syntax(code, self.lexer_name, theme=self.theme, line_numbers=True)
45
+ yield syntax
46
+
47
+
48
+ class MarkdownWithLineNumbers(Markdown):
49
+ """Markdown renderer that keeps line numbers for fenced code blocks."""
50
+
51
+ elements = Markdown.elements.copy()
52
+ elements.update({
53
+ "fence": CodeBlockWithLineNumbers,
54
+ "code_block": CodeBlockWithLineNumbers,
55
+ })
56
+
57
+
58
+ class ThinkMarkdown:
59
+ """Markdown renderer that dims content inside <think> tags."""
60
+
61
+ def __init__(
62
+ self,
63
+ markup: str,
64
+ code_theme: str = "monokai",
65
+ use_line_numbers: bool = False,
66
+ ) -> None:
67
+ marked = _mark_think_sections(markup)
68
+ markdown_cls = MarkdownWithLineNumbers if use_line_numbers else Markdown
69
+ self._markdown = markdown_cls(marked, code_theme=code_theme)
70
+
71
+ def __rich_console__(self, console: Console, options):
72
+ segments = console.render(self._markdown, options)
73
+ start_marker = THINK_START_MARKER
74
+ end_marker = THINK_END_MARKER
75
+ markers = (start_marker, end_marker)
76
+ in_think = False
77
+ carry = ""
78
+ carry_style = None
79
+
80
+ def pending_suffix(text: str) -> tuple[str, str]:
81
+ max_prefix = 0
82
+ for marker in markers:
83
+ for i in range(1, len(marker)):
84
+ if text.endswith(marker[:i]) and i > max_prefix:
85
+ max_prefix = i
86
+ if max_prefix:
87
+ return text[:-max_prefix], text[-max_prefix:]
88
+ return text, ""
89
+
90
+ def emit(text: str, style: Style | None):
91
+ if not text:
92
+ return
93
+ if in_think:
94
+ style = (style or Style()) + Style(dim=True)
95
+ yield Segment(text, style)
96
+
97
+ for segment in segments:
98
+ if segment.control:
99
+ if carry:
100
+ yield from emit(carry, carry_style)
101
+ carry = ""
102
+ carry_style = None
103
+ yield segment
104
+ continue
105
+
106
+ text = segment.text
107
+ style = segment.style
108
+
109
+ if carry:
110
+ if carry_style != style:
111
+ yield from emit(carry, carry_style)
112
+ carry = ""
113
+ carry_style = None
114
+ else:
115
+ text = carry + text
116
+ carry = ""
117
+ carry_style = None
118
+
119
+ output = ""
120
+ index = 0
121
+ while index < len(text):
122
+ if text.startswith(start_marker, index):
123
+ if output:
124
+ yield from emit(output, style)
125
+ output = ""
126
+ in_think = True
127
+ index += len(start_marker)
128
+ continue
129
+ if text.startswith(end_marker, index):
130
+ if output:
131
+ yield from emit(output, style)
132
+ output = ""
133
+ in_think = False
134
+ index += len(end_marker)
135
+ continue
136
+ output += text[index]
137
+ index += 1
138
+
139
+ output, carry = pending_suffix(output)
140
+ if output:
141
+ yield from emit(output, style)
142
+ if carry:
143
+ carry_style = style
144
+
145
+ if carry:
146
+ yield from emit(carry, carry_style)
147
+
148
+
149
+ class PrefixedRenderable:
150
+ """Render a prefix before the first line and an indent after newlines."""
151
+
152
+ def __init__(
153
+ self,
154
+ renderable,
155
+ prefix: str,
156
+ prefix_style: Style | None = None,
157
+ indent: str | None = None,
158
+ ) -> None:
159
+ self.renderable = renderable
160
+ self.prefix = prefix
161
+ self.prefix_style = prefix_style
162
+ self.indent = indent if indent is not None else " " * len(prefix)
163
+
164
+ def __rich_console__(self, console: Console, options):
165
+ yield Segment(self.prefix, self.prefix_style)
166
+
167
+ for segment in console.render(self.renderable, options):
168
+ if segment.control:
169
+ yield segment
170
+ continue
171
+
172
+ text = segment.text
173
+ style = segment.style
174
+
175
+ if "\n" not in text:
176
+ yield segment
177
+ continue
178
+
179
+ parts = text.split("\n")
180
+ for index, part in enumerate(parts):
181
+ if part:
182
+ yield Segment(part, style)
183
+ if index < len(parts) - 1:
184
+ yield Segment("\n", style)
185
+ yield Segment(self.indent, None)