streamdown 0.21.0__py3-none-any.whl → 0.22.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.
- streamdown/sd.py +51 -40
- {streamdown-0.21.0.dist-info → streamdown-0.22.0.dist-info}/METADATA +30 -11
- streamdown-0.22.0.dist-info/RECORD +9 -0
- streamdown/ss +0 -1
- streamdown/ss1 +0 -42
- streamdown-0.21.0.dist-info/RECORD +0 -11
- {streamdown-0.21.0.dist-info → streamdown-0.22.0.dist-info}/WHEEL +0 -0
- {streamdown-0.21.0.dist-info → streamdown-0.22.0.dist-info}/entry_points.txt +0 -0
- {streamdown-0.21.0.dist-info → streamdown-0.22.0.dist-info}/licenses/LICENSE.MIT +0 -0
streamdown/sd.py
CHANGED
|
@@ -55,7 +55,7 @@ Savebrace = true
|
|
|
55
55
|
[style]
|
|
56
56
|
Margin = 2
|
|
57
57
|
ListIndent = 2
|
|
58
|
-
PrettyPad =
|
|
58
|
+
PrettyPad = true
|
|
59
59
|
PrettyBroken = true
|
|
60
60
|
Width = 0
|
|
61
61
|
HSV = [0.8, 0.5, 0.5]
|
|
@@ -68,19 +68,18 @@ Bright = { H = 1.00, S = 2.00, V = 2.00 }
|
|
|
68
68
|
Syntax = "dracula"
|
|
69
69
|
"""
|
|
70
70
|
|
|
71
|
-
def ensure_config_file():
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
def ensure_config_file(config):
|
|
72
|
+
if config:
|
|
73
|
+
config_path = config
|
|
74
|
+
else:
|
|
75
|
+
config_dir = appdirs.user_config_dir("streamdown")
|
|
76
|
+
os.makedirs(config_dir, exist_ok=True)
|
|
77
|
+
config_path = os.path.join(config_dir, "config.toml")
|
|
78
|
+
if not os.path.exists(config_path):
|
|
79
|
+
open(config_path, 'w').write(default_toml)
|
|
80
|
+
|
|
77
81
|
return config_path, open(config_path).read()
|
|
78
82
|
|
|
79
|
-
config_toml_path, config_toml_content = ensure_config_file()
|
|
80
|
-
config = toml.loads(config_toml_content)
|
|
81
|
-
_style = toml.loads(default_toml).get('style') | config.get("style", {})
|
|
82
|
-
_features = toml.loads(default_toml).get('features') | config.get("features", {})
|
|
83
|
-
H, S, V = _style.get("HSV")
|
|
84
83
|
|
|
85
84
|
FG = "\033[38;2;"
|
|
86
85
|
BG = "\033[48;2;"
|
|
@@ -115,8 +114,6 @@ def debug_write(text):
|
|
|
115
114
|
|
|
116
115
|
def savebrace():
|
|
117
116
|
if state.Savebrace and state.code_buffer_raw:
|
|
118
|
-
tmp_dir = os.path.join(tempfile.gettempdir(), "sd")
|
|
119
|
-
os.makedirs(tmp_dir, exist_ok=True)
|
|
120
117
|
path = os.path.join(tempfile.gettempdir(), "sd", 'savebrace')
|
|
121
118
|
with open(path, "a") as f:
|
|
122
119
|
f.write(state.code_buffer_raw + "\x00")
|
|
@@ -126,7 +123,6 @@ class Goto(Exception):
|
|
|
126
123
|
pass
|
|
127
124
|
|
|
128
125
|
class Style:
|
|
129
|
-
PrettyPad = _style.get("PrettyPad")
|
|
130
126
|
pass
|
|
131
127
|
|
|
132
128
|
class Code:
|
|
@@ -150,12 +146,6 @@ class ParseState:
|
|
|
150
146
|
self.scrape_ix = 0
|
|
151
147
|
self.terminal = None
|
|
152
148
|
|
|
153
|
-
self.CodeSpaces = _features.get("CodeSpaces")
|
|
154
|
-
self.Clipboard = _features.get("Clipboard")
|
|
155
|
-
self.Logging = _features.get("Logging")
|
|
156
|
-
self.Timeout = _features.get("Timeout")
|
|
157
|
-
self.Savebrace = _features.get("Savebrace")
|
|
158
|
-
|
|
159
149
|
self.WidthArg = None
|
|
160
150
|
self.WidthFull = None
|
|
161
151
|
self.WidthWrap = False
|
|
@@ -319,6 +309,10 @@ def code_wrap(text_in):
|
|
|
319
309
|
for i in range(mywidth, len(text), mywidth):
|
|
320
310
|
res.append(text[i : i + mywidth])
|
|
321
311
|
|
|
312
|
+
# sometimes just a newline wraps ... this isn't what we want actually
|
|
313
|
+
if res[-1].strip() == '':
|
|
314
|
+
res.pop()
|
|
315
|
+
|
|
322
316
|
return (indent, res)
|
|
323
317
|
|
|
324
318
|
|
|
@@ -700,8 +694,13 @@ def parse(stream):
|
|
|
700
694
|
state.code_first_line = True
|
|
701
695
|
state.bg = f"{BG}{Style.Dark}"
|
|
702
696
|
state.where_from = "code pad"
|
|
703
|
-
if Style.PrettyPad:
|
|
697
|
+
if Style.PrettyPad or Style.PrettyBroken:
|
|
698
|
+
if not Style.PrettyPad:
|
|
699
|
+
yield ""
|
|
700
|
+
|
|
704
701
|
yield Style.Codepad[0]
|
|
702
|
+
else:
|
|
703
|
+
yield ""
|
|
705
704
|
|
|
706
705
|
logging.debug(f"In code: ({state.in_code})")
|
|
707
706
|
|
|
@@ -734,8 +733,13 @@ def parse(stream):
|
|
|
734
733
|
state.bg = BGRESET
|
|
735
734
|
|
|
736
735
|
state.where_from = "code pad"
|
|
737
|
-
if Style.PrettyPad:
|
|
738
|
-
yield Style.Codepad[1]
|
|
736
|
+
if Style.PrettyPad or Style.PrettyBroken:
|
|
737
|
+
yield Style.Codepad[1]
|
|
738
|
+
if not Style.PrettyPad:
|
|
739
|
+
yield ""
|
|
740
|
+
|
|
741
|
+
else:
|
|
742
|
+
yield RESET
|
|
739
743
|
|
|
740
744
|
logging.debug(f"code: {state.in_code}")
|
|
741
745
|
state.emit_flush = True
|
|
@@ -798,12 +802,10 @@ def parse(stream):
|
|
|
798
802
|
if highlighted_code.endswith(FGRESET + "\n"):
|
|
799
803
|
highlighted_code = highlighted_code[: -(1 + len(FGRESET))]
|
|
800
804
|
|
|
801
|
-
#print(bytes(highlighted_code, 'utf-8'))
|
|
802
|
-
|
|
803
805
|
# turns out highlight will eat leading newlines on empty lines
|
|
804
806
|
vislen = visible_length(state.code_buffer.lstrip())
|
|
805
807
|
|
|
806
|
-
delta =
|
|
808
|
+
delta = -2
|
|
807
809
|
while visible_length(highlighted_code[:(state.code_gen-delta)]) > vislen:
|
|
808
810
|
delta += 1
|
|
809
811
|
|
|
@@ -992,8 +994,8 @@ def ansi2hex(ansi_code):
|
|
|
992
994
|
r, g, b = map(int, parts)
|
|
993
995
|
return f"#{r:02x}{g:02x}{b:02x}"
|
|
994
996
|
|
|
995
|
-
def apply_multipliers(name, H, S, V):
|
|
996
|
-
m =
|
|
997
|
+
def apply_multipliers(style, name, H, S, V):
|
|
998
|
+
m = style.get(name)
|
|
997
999
|
r, g, b = colorsys.hsv_to_rgb(min(1.0, H * m["H"]), min(1.0, S * m["S"]), min(1.0, V * m["V"]))
|
|
998
1000
|
return ';'.join([str(int(x * 256)) for x in [r, g, b]]) + "m"
|
|
999
1001
|
|
|
@@ -1014,40 +1016,49 @@ def width_calc():
|
|
|
1014
1016
|
|
|
1015
1017
|
state.Width = state.WidthFull - 2 * Style.Margin
|
|
1016
1018
|
pre = state.space_left(listwidth=True) if Style.PrettyBroken else ''
|
|
1019
|
+
design = [FG, '▄','▀'] if Style.PrettyPad else [BG, ' ',' ']
|
|
1017
1020
|
Style.Codepad = [
|
|
1018
|
-
f"{pre}{RESET}{
|
|
1019
|
-
f"{pre}{RESET}{
|
|
1021
|
+
f"{pre}{RESET}{design[0]}{Style.Dark}{design[1] * state.full_width()}{RESET}\n",
|
|
1022
|
+
f"{pre}{RESET}{design[0]}{Style.Dark}{design[2] * state.full_width()}{RESET}"
|
|
1020
1023
|
]
|
|
1021
1024
|
|
|
1022
1025
|
def main():
|
|
1023
|
-
global H, S, V
|
|
1024
|
-
|
|
1025
1026
|
parser = ArgumentParser(description="Streamdown - A Streaming markdown renderer for modern terminals")
|
|
1026
1027
|
parser.add_argument("filenameList", nargs="*", help="Input file to process (also takes stdin)")
|
|
1027
1028
|
parser.add_argument("-l", "--loglevel", default="INFO", help="Set the logging level")
|
|
1028
|
-
parser.add_argument("-
|
|
1029
|
+
parser.add_argument("-b", "--base", default=None, help="Set the hsv base: h,s,v")
|
|
1030
|
+
parser.add_argument("-c", "--config", default=None, help="Use a custom config")
|
|
1029
1031
|
parser.add_argument("-w", "--width", default="0", help="Set the width WIDTH")
|
|
1030
1032
|
parser.add_argument("-e", "--exec", help="Wrap a program EXEC for more 'proper' i/o handling")
|
|
1031
1033
|
parser.add_argument("-s", "--scrape", help="Scrape code snippets to a directory SCRAPE")
|
|
1032
1034
|
args = parser.parse_args()
|
|
1033
1035
|
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
+
config_toml_path, config_toml_content = ensure_config_file(args.config)
|
|
1037
|
+
config = toml.loads(config_toml_content)
|
|
1038
|
+
style = toml.loads(default_toml).get('style') | config.get("style", {})
|
|
1039
|
+
features = toml.loads(default_toml).get('features') | config.get("features", {})
|
|
1040
|
+
H, S, V = style.get("HSV")
|
|
1041
|
+
|
|
1042
|
+
if args.base:
|
|
1043
|
+
env_colors = args.base.split(",")
|
|
1036
1044
|
if len(env_colors) > 0: H = float(env_colors[0])
|
|
1037
1045
|
if len(env_colors) > 1: S = float(env_colors[1])
|
|
1038
1046
|
if len(env_colors) > 2: V = float(env_colors[2])
|
|
1039
1047
|
|
|
1040
1048
|
for color in ["Dark", "Mid", "Symbol", "Head", "Grey", "Bright"]:
|
|
1041
|
-
setattr(Style, color, apply_multipliers(color, H, S, V))
|
|
1042
|
-
for attr in ['PrettyBroken', 'Margin', 'ListIndent', 'Syntax']:
|
|
1043
|
-
setattr(Style, attr,
|
|
1049
|
+
setattr(Style, color, apply_multipliers(style, color, H, S, V))
|
|
1050
|
+
for attr in ['PrettyPad', 'PrettyBroken', 'Margin', 'ListIndent', 'Syntax']:
|
|
1051
|
+
setattr(Style, attr, style.get(attr))
|
|
1052
|
+
for attr in ['CodeSpaces', 'Clipboard', 'Logging', 'Timeout', 'Savebrace']:
|
|
1053
|
+
setattr(state, attr, features.get(attr))
|
|
1054
|
+
|
|
1044
1055
|
|
|
1045
1056
|
if args.scrape:
|
|
1046
1057
|
os.makedirs(args.scrape, exist_ok=True)
|
|
1047
1058
|
state.scrape = args.scrape
|
|
1048
1059
|
|
|
1049
1060
|
Style.MarginSpaces = " " * Style.Margin
|
|
1050
|
-
state.WidthArg = int(args.width) or
|
|
1061
|
+
state.WidthArg = int(args.width) or style.get("Width") or 0
|
|
1051
1062
|
Style.Blockquote = f"{FG}{Style.Grey}│ "
|
|
1052
1063
|
width_calc()
|
|
1053
1064
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: streamdown
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.22.0
|
|
4
4
|
Summary: A streaming markdown renderer for modern terminals with syntax highlighting
|
|
5
5
|
Project-URL: Homepage, https://github.com/kristopolous/Streamdown
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/kristopolous/Streamdown/issues
|
|
@@ -38,6 +38,10 @@ Description-Content-Type: text/markdown
|
|
|
38
38
|
|
|
39
39
|
Streamdown works with any streaming markdown such as [simonw's llm](https://github.com/simonw/llm) or even something basic like curl.
|
|
40
40
|
|
|
41
|
+
It is designed for AI and can be used to do parser based sophisticated pipelines and routing, cracking open various monolithic AI solutions to permit them to integrate. Think of it as output level routing at the semantic level.
|
|
42
|
+
|
|
43
|
+
You can also just use it like a normal person.
|
|
44
|
+
|
|
41
45
|
It supports standard piping and files as arguments like any normal pager but can also run as a wrapper so you retain full keyboard interactivity. Arrow keys, control, alt, all still work.
|
|
42
46
|
```bash
|
|
43
47
|
$ pip install streamdown
|
|
@@ -59,7 +63,7 @@ The optional `Clipboard` feature puts the final codeblock into your clipboard. S
|
|
|
59
63
|
[links.webm](https://github.com/user-attachments/assets/a5f71791-7c58-4183-ad3b-309f470c08a3)
|
|
60
64
|
|
|
61
65
|
### As well as everything else...
|
|
62
|
-
Here's the `Savebrace` feature with `screen-query` and `
|
|
66
|
+
Here's the `Savebrace` feature with `screen-query` and `sq-picker` from [llmehelp](https://github.com/kristopolous/llmehelp). You can have an ongoing conversation in tmux with your terminal session. Then use popups and fzf to insert command or coding blocks all with a keystroke.
|
|
63
67
|
|
|
64
68
|
This allows you to interactively debug in a way that the agent doesn't just wander off doing silly things.
|
|
65
69
|
|
|
@@ -135,26 +139,41 @@ Clipboard = false
|
|
|
135
139
|
## Command Line
|
|
136
140
|
The most exciting feature here is `--exec` with it you can do full readline support like this:
|
|
137
141
|
|
|
138
|
-
|
|
142
|
+
```shell
|
|
143
|
+
$ sd --exec "llm chat"
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
And now you have all your readline stuff. It's pretty great. (Also see the Day50 shellwrap project.)
|
|
139
147
|
|
|
140
|
-
|
|
148
|
+
It's also worth noting that things like the `-c` aren't "broken" with regard to file input. You can do something like this:
|
|
141
149
|
|
|
142
150
|
```shell
|
|
143
|
-
|
|
151
|
+
$ sd -c <(echo "[style]\nMargin=10")
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
To override the margin.
|
|
155
|
+
|
|
156
|
+
```shell
|
|
157
|
+
usage: sd [-h] [-l LOGLEVEL] [-b BASE] [-c CONFIG] [-w WIDTH] [-e EXEC]
|
|
158
|
+
[-s SCRAPE] [filenameList ...]
|
|
159
|
+
|
|
160
|
+
Streamdown - A Streaming markdown renderer for modern terminals
|
|
144
161
|
|
|
145
162
|
positional arguments:
|
|
146
163
|
filenameList Input file to process (also takes stdin)
|
|
147
164
|
|
|
148
|
-
|
|
165
|
+
optional arguments:
|
|
149
166
|
-h, --help show this help message and exit
|
|
150
167
|
-l LOGLEVEL, --loglevel LOGLEVEL
|
|
151
168
|
Set the logging level
|
|
152
|
-
-
|
|
153
|
-
|
|
169
|
+
-b BASE, --base BASE Set the hsv base: h,s,v
|
|
170
|
+
-c CONFIG, --config CONFIG
|
|
171
|
+
Use a custom config
|
|
154
172
|
-w WIDTH, --width WIDTH
|
|
155
|
-
Set the width
|
|
156
|
-
-e EXEC, --exec EXEC Wrap a program for more 'proper' i/o handling
|
|
157
|
-
|
|
173
|
+
Set the width WIDTH
|
|
174
|
+
-e EXEC, --exec EXEC Wrap a program EXEC for more 'proper' i/o handling
|
|
175
|
+
-s SCRAPE, --scrape SCRAPE
|
|
176
|
+
Scrape code snippets to a directory SCRAPE
|
|
158
177
|
```
|
|
159
178
|
|
|
160
179
|
## Demo
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
streamdown/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
streamdown/sd.py,sha256=unpjFxiUkjHw9XNZ8ziaOaka4s9qPpV5lwaeGz6pzlo,41981
|
|
3
|
+
streamdown/plugins/README.md,sha256=KWqYELs9WkKJmuDzYv3cvPlZMkArsNCBUe4XDoTLjLA,1143
|
|
4
|
+
streamdown/plugins/latex.py,sha256=xZMGMdx_Sw4X1piZejXFHfEG9qazU4fGeceiMI0h13Y,648
|
|
5
|
+
streamdown-0.22.0.dist-info/METADATA,sha256=jN3R2SE6M7UWfpb9a2IdNGDMfKNL5CBAEj0UaunowKg,9658
|
|
6
|
+
streamdown-0.22.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
7
|
+
streamdown-0.22.0.dist-info/entry_points.txt,sha256=HroKFsFMGf_h9PRTE96NjvjJQWupMW5TGP5RGUr1O_Q,74
|
|
8
|
+
streamdown-0.22.0.dist-info/licenses/LICENSE.MIT,sha256=SnY46EPirUsF20dZDR8HpyVgS2_4Tjxuc6f-4OdqO7U,1070
|
|
9
|
+
streamdown-0.22.0.dist-info/RECORD,,
|
streamdown/ss
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
* **Model Card:** Always read the model card on the Hugging Face Hub ([https://huggingface.co/microsoft/bitnet-b1.58-2B-4T](https://huggingface.co/microsoft/bitnet-b1.58-2B-4T)) for important information about the model, its intended use, limitations, and potential biases.
|
streamdown/ss1
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
* `model.safetensors`: The name of the file you want to download. You'll need to know the exact filename. You can find the files in the model repository on the Hugging Face Hub website ([https://huggingface.co/microsoft/bitnet-b1.58-2B-4T](https://huggingface.co/microsoft/bitnet-b1.58-2B-4T)). Look under the "Files and versions" tab. `safetensors` is the preferred format for model weights now. If it's a `.bin` file, you can download that instead.
|
|
2
|
-
* `--local-dir ./bitnet-b1.58-2B-4T`: The directory to save the file to.
|
|
3
|
-
|
|
4
|
-
* **Download using `transformers` library (recommended for most use cases):**
|
|
5
|
-
|
|
6
|
-
The `transformers` library provides a convenient way to download and cache models. This is often the easiest approach if you're using the model with `transformers`. You don't *directly* use the `huggingface-cli` for this, but it's worth knowing.
|
|
7
|
-
|
|
8
|
-
```python
|
|
9
|
-
from transformers import AutoModelForCausalLM, AutoTokenizer
|
|
10
|
-
|
|
11
|
-
model_name = "microsoft/bitnet-b1.58-2B-4T"
|
|
12
|
-
|
|
13
|
-
tokenizer = AutoTokenizer.from_pretrained(model_name)
|
|
14
|
-
model = AutoModelForCausalLM.from_pretrained(model_name)
|
|
15
|
-
|
|
16
|
-
# The model and tokenizer will be downloaded and cached in your
|
|
17
|
-
# transformers cache directory (usually ~/.cache/huggingface/transformers).
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
This approach automatically handles downloading the necessary files and caching them for future use. It also handles the correct file formats and configurations.
|
|
21
|
-
|
|
22
|
-
**4. Checking the Download**
|
|
23
|
-
|
|
24
|
-
After the download completes, verify that the files are in the specified directory. You can use `ls` (Linux/macOS) or `dir` (Windows) to list the contents of the directory.
|
|
25
|
-
|
|
26
|
-
**Important Considerations:**
|
|
27
|
-
|
|
28
|
-
* **Disk Space:** The `bitnet-b1.58-2B-4T` model is quite large (several gigabytes). Make sure you have enough free disk space before downloading.
|
|
29
|
-
* **Network Connection:** A stable and fast internet connection is essential for a smooth download.
|
|
30
|
-
* **Caching:** The Hugging Face Hub and `transformers` library use caching to avoid re-downloading models unnecessarily. The default cache directory is usually `~/.cache/huggingface/transformers`.
|
|
31
|
-
* **File Formats:** Models are often stored in `safetensors` or `.bin` formats. `safetensors` is generally preferred for security and performance.
|
|
32
|
-
* **Model Card:** Always read the model card on the Hugging Face Hub ([https://huggingface.co/microsoft/bitnet-b1.58-2B-4T](https://huggingface.co/microsoft/bitnet-b1.58-2B-4T)) for important information about the model, its intended use, limitations, and potential biases.
|
|
33
|
-
* **Gated Models:** Some models require you to accept terms of use before you can download them. The `huggingface-cli login` command will guide you through this process if necessary.
|
|
34
|
-
|
|
35
|
-
**Example Workflow (Recommended):**
|
|
36
|
-
|
|
37
|
-
1. `huggingface-cli login` (if not already logged in)
|
|
38
|
-
2. Use the `transformers` library in a Python script to download and load the model (as shown in the example above). This is the most convenient and reliable method for most use cases.
|
|
39
|
-
|
|
40
|
-
Let me know if you have any other questions or if you'd like help with a specific task related to this model!
|
|
41
|
-
|
|
42
|
-
>
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
streamdown/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
streamdown/sd.py,sha256=GmxttpBmMR3yJU2UGM9ESOYqFQMU28HYhVwAKcsMERM,41579
|
|
3
|
-
streamdown/ss,sha256=sel_phpaecrw6WGIHRLROsD7BFShf0rSDHheflwdUn8,277
|
|
4
|
-
streamdown/ss1,sha256=CUVf86_2zeAle2oQCeTfWYqtHBrAFR_UgvptuYMQzFU,3151
|
|
5
|
-
streamdown/plugins/README.md,sha256=KWqYELs9WkKJmuDzYv3cvPlZMkArsNCBUe4XDoTLjLA,1143
|
|
6
|
-
streamdown/plugins/latex.py,sha256=xZMGMdx_Sw4X1piZejXFHfEG9qazU4fGeceiMI0h13Y,648
|
|
7
|
-
streamdown-0.21.0.dist-info/METADATA,sha256=AcCbhBJvkAvdcB-4_1qDhXkrAp02-4vsKWPaoLW2jXg,8843
|
|
8
|
-
streamdown-0.21.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
9
|
-
streamdown-0.21.0.dist-info/entry_points.txt,sha256=HroKFsFMGf_h9PRTE96NjvjJQWupMW5TGP5RGUr1O_Q,74
|
|
10
|
-
streamdown-0.21.0.dist-info/licenses/LICENSE.MIT,sha256=SnY46EPirUsF20dZDR8HpyVgS2_4Tjxuc6f-4OdqO7U,1070
|
|
11
|
-
streamdown-0.21.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|