convoviz 0.2.10__tar.gz → 0.2.12__tar.gz
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.
- {convoviz-0.2.10 → convoviz-0.2.12}/PKG-INFO +5 -8
- {convoviz-0.2.10 → convoviz-0.2.12}/README.md +4 -7
- convoviz-0.2.12/convoviz/assets/stopwords.txt +1 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/renderers/markdown.py +62 -2
- {convoviz-0.2.10 → convoviz-0.2.12}/pyproject.toml +1 -1
- convoviz-0.2.10/convoviz/assets/stopwords.txt +0 -75
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/__init__.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/__main__.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/analysis/__init__.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/analysis/graphs.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/analysis/wordcloud.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/colormaps.txt +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/AmaticSC-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/ArchitectsDaughter-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/BebasNeue-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/Borel-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/Courgette-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/CroissantOne-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/Handjet-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/IndieFlower-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/Kalam-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/Lobster-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/MartianMono-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/MartianMono-Thin.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/Montserrat-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/Mooli-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/Pacifico-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/PlayfairDisplay-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/Raleway-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/RobotoMono-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/RobotoMono-Thin.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/RobotoSlab-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/RobotoSlab-Thin.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/Ruwudu-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/Sacramento-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/SedgwickAveDisplay-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/ShadowsIntoLight-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/TitilliumWeb-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/Yellowtail-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/YsabeauOffice-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/YsabeauSC-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/YsabeauSC-Thin.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/assets/fonts/Zeyada-Regular.ttf +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/cli.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/config.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/exceptions.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/interactive.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/io/__init__.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/io/assets.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/io/loaders.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/io/writers.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/models/__init__.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/models/collection.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/models/conversation.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/models/message.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/models/node.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/pipeline.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/py.typed +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/renderers/__init__.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/renderers/yaml.py +0 -0
- {convoviz-0.2.10 → convoviz-0.2.12}/convoviz/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: convoviz
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.12
|
|
4
4
|
Summary: Get analytics and visualizations on your ChatGPT data!
|
|
5
5
|
Keywords: markdown,chatgpt,openai,visualization,analytics,json,export,data-analysis,obsidian
|
|
6
6
|
Author: Mohamed Cheikh Sidiya
|
|
@@ -124,7 +124,10 @@ And if you've had a great experience, consider giving the project a star ⭐. It
|
|
|
124
124
|
|
|
125
125
|
## Notes
|
|
126
126
|
|
|
127
|
-
This is just a small thing I coded to help me see my convos in beautiful markdown. It was originally built with [Obsidian](https://obsidian.md/) (my go-to note-taking app) in mind, but the default output is standard Markdown
|
|
127
|
+
This is just a small thing I coded to help me see my convos in beautiful markdown. It was originally built with [Obsidian](https://obsidian.md/) (my go-to note-taking app) in mind, but the default output is standard Markdown.
|
|
128
|
+
|
|
129
|
+
You can choose obsidian flavored md in the cli to get extra features like:
|
|
130
|
+
- model reasoning (`reasoning_recap`, `thoughts`) rendered as collapsible `> [!NOTE]-` callouts instead of being hidden.
|
|
128
131
|
|
|
129
132
|
I wasn't a fan of the clunky, and sometimes paid, browser extensions.
|
|
130
133
|
|
|
@@ -136,12 +139,6 @@ It should(?) also work as library, so you can import and use the models and func
|
|
|
136
139
|
|
|
137
140
|
Convoviz uses NLTK stopwords for word clouds. If you’re offline and NLTK data isn’t already installed, pre-download it once:
|
|
138
141
|
|
|
139
|
-
```bash
|
|
140
|
-
python -c "import nltk; nltk.download('stopwords')"
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
If you’re using `uv` without a global install, you can run:
|
|
144
|
-
|
|
145
142
|
```bash
|
|
146
143
|
uv run python -c "import nltk; nltk.download('stopwords')"
|
|
147
144
|
```
|
|
@@ -98,7 +98,10 @@ And if you've had a great experience, consider giving the project a star ⭐. It
|
|
|
98
98
|
|
|
99
99
|
## Notes
|
|
100
100
|
|
|
101
|
-
This is just a small thing I coded to help me see my convos in beautiful markdown. It was originally built with [Obsidian](https://obsidian.md/) (my go-to note-taking app) in mind, but the default output is standard Markdown
|
|
101
|
+
This is just a small thing I coded to help me see my convos in beautiful markdown. It was originally built with [Obsidian](https://obsidian.md/) (my go-to note-taking app) in mind, but the default output is standard Markdown.
|
|
102
|
+
|
|
103
|
+
You can choose obsidian flavored md in the cli to get extra features like:
|
|
104
|
+
- model reasoning (`reasoning_recap`, `thoughts`) rendered as collapsible `> [!NOTE]-` callouts instead of being hidden.
|
|
102
105
|
|
|
103
106
|
I wasn't a fan of the clunky, and sometimes paid, browser extensions.
|
|
104
107
|
|
|
@@ -110,12 +113,6 @@ It should(?) also work as library, so you can import and use the models and func
|
|
|
110
113
|
|
|
111
114
|
Convoviz uses NLTK stopwords for word clouds. If you’re offline and NLTK data isn’t already installed, pre-download it once:
|
|
112
115
|
|
|
113
|
-
```bash
|
|
114
|
-
python -c "import nltk; nltk.download('stopwords')"
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
If you’re using `uv` without a global install, you can run:
|
|
118
|
-
|
|
119
116
|
```bash
|
|
120
117
|
uv run python -c "import nltk; nltk.download('stopwords')"
|
|
121
118
|
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -62,6 +62,32 @@ def code_block(text: str, lang: str = "python") -> str:
|
|
|
62
62
|
return f"```{lang}\n{text}\n```"
|
|
63
63
|
|
|
64
64
|
|
|
65
|
+
def render_obsidian_callout(
|
|
66
|
+
content: str,
|
|
67
|
+
title: str,
|
|
68
|
+
callout_type: str = "NOTE",
|
|
69
|
+
collapsed: bool = True,
|
|
70
|
+
) -> str:
|
|
71
|
+
"""Render content as an Obsidian collapsible callout.
|
|
72
|
+
|
|
73
|
+
Syntax: > [!TYPE]+/- Title
|
|
74
|
+
This is Obsidian-specific; on GitHub/standard markdown it renders as a blockquote.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
content: The content to wrap
|
|
78
|
+
title: The callout title
|
|
79
|
+
callout_type: The callout type (NOTE, TIP, WARNING, etc.)
|
|
80
|
+
collapsed: Whether to default to collapsed (-) or expanded (+)
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
Markdown callout string
|
|
84
|
+
"""
|
|
85
|
+
fold = "-" if collapsed else "+"
|
|
86
|
+
lines = content.strip().split("\n")
|
|
87
|
+
quoted_lines = [f"> {line}" for line in lines]
|
|
88
|
+
return f"> [!{callout_type}]{fold} {title}\n" + "\n".join(quoted_lines)
|
|
89
|
+
|
|
90
|
+
|
|
65
91
|
def render_message_header(role: str, headers: AuthorHeaders) -> str:
|
|
66
92
|
"""Get the markdown header for a message author.
|
|
67
93
|
|
|
@@ -97,11 +123,20 @@ def render_node_header(node: Node, headers: AuthorHeaders) -> str:
|
|
|
97
123
|
return render_message_header(node.message.author.role, headers) + "\n"
|
|
98
124
|
|
|
99
125
|
|
|
126
|
+
# Content types that can be rendered as collapsible callouts in Obsidian
|
|
127
|
+
OBSIDIAN_COLLAPSIBLE_TYPES: dict[str, tuple[str, str]] = {
|
|
128
|
+
# content_type: (callout_type, title)
|
|
129
|
+
"reasoning_recap": ("NOTE", "🧠 AI Reasoning"),
|
|
130
|
+
"thoughts": ("NOTE", "💭 AI Thoughts"),
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
|
|
100
134
|
def render_node(
|
|
101
135
|
node: Node,
|
|
102
136
|
headers: AuthorHeaders,
|
|
103
137
|
use_dollar_latex: bool = False,
|
|
104
138
|
asset_resolver: Callable[[str], str | None] | None = None,
|
|
139
|
+
flavor: str = "standard",
|
|
105
140
|
) -> str:
|
|
106
141
|
"""Render a complete node as markdown.
|
|
107
142
|
|
|
@@ -110,6 +145,7 @@ def render_node(
|
|
|
110
145
|
headers: Configuration for author headers
|
|
111
146
|
use_dollar_latex: Whether to convert LaTeX delimiters to dollars
|
|
112
147
|
asset_resolver: Function to resolve asset IDs to paths
|
|
148
|
+
flavor: Markdown flavor ("standard" or "obsidian")
|
|
113
149
|
|
|
114
150
|
Returns:
|
|
115
151
|
Complete markdown string for the node
|
|
@@ -117,6 +153,26 @@ def render_node(
|
|
|
117
153
|
if node.message is None:
|
|
118
154
|
return ""
|
|
119
155
|
|
|
156
|
+
content_type = node.message.content.content_type
|
|
157
|
+
|
|
158
|
+
# For Obsidian flavor, render certain hidden types as collapsible callouts
|
|
159
|
+
# No separator (---) since these are visually distinct and may appear consecutively
|
|
160
|
+
if flavor == "obsidian" and content_type in OBSIDIAN_COLLAPSIBLE_TYPES:
|
|
161
|
+
try:
|
|
162
|
+
text = node.message.text
|
|
163
|
+
except MessageContentError:
|
|
164
|
+
text = ""
|
|
165
|
+
|
|
166
|
+
if text.strip():
|
|
167
|
+
callout_type, title = OBSIDIAN_COLLAPSIBLE_TYPES[content_type]
|
|
168
|
+
callout = render_obsidian_callout(
|
|
169
|
+
content=text,
|
|
170
|
+
title=title,
|
|
171
|
+
callout_type=callout_type,
|
|
172
|
+
collapsed=True,
|
|
173
|
+
)
|
|
174
|
+
return f"\n{callout}\n"
|
|
175
|
+
|
|
120
176
|
if node.message.is_hidden:
|
|
121
177
|
return ""
|
|
122
178
|
|
|
@@ -194,7 +250,7 @@ def render_conversation(
|
|
|
194
250
|
Complete markdown document string
|
|
195
251
|
"""
|
|
196
252
|
use_dollar_latex = config.markdown.latex_delimiters == "dollars"
|
|
197
|
-
|
|
253
|
+
flavor = config.markdown.flavor
|
|
198
254
|
|
|
199
255
|
# Start with YAML header
|
|
200
256
|
markdown = render_yaml_header(conversation, config.yaml)
|
|
@@ -203,7 +259,11 @@ def render_conversation(
|
|
|
203
259
|
for node in _ordered_nodes(conversation):
|
|
204
260
|
if node.message:
|
|
205
261
|
markdown += render_node(
|
|
206
|
-
node,
|
|
262
|
+
node,
|
|
263
|
+
headers,
|
|
264
|
+
use_dollar_latex,
|
|
265
|
+
asset_resolver=asset_resolver,
|
|
266
|
+
flavor=flavor,
|
|
207
267
|
)
|
|
208
268
|
|
|
209
269
|
return markdown
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
# Python
|
|
2
|
-
def
|
|
3
|
-
class
|
|
4
|
-
import
|
|
5
|
-
from
|
|
6
|
-
as
|
|
7
|
-
elif
|
|
8
|
-
finally
|
|
9
|
-
yield
|
|
10
|
-
pass
|
|
11
|
-
lambda
|
|
12
|
-
async
|
|
13
|
-
await
|
|
14
|
-
nonlocal
|
|
15
|
-
assert
|
|
16
|
-
self
|
|
17
|
-
cls
|
|
18
|
-
# JavaScript / TypeScript
|
|
19
|
-
const
|
|
20
|
-
let
|
|
21
|
-
var
|
|
22
|
-
function
|
|
23
|
-
export
|
|
24
|
-
default
|
|
25
|
-
extends
|
|
26
|
-
implements
|
|
27
|
-
static
|
|
28
|
-
# Java / C#
|
|
29
|
-
final
|
|
30
|
-
abstract
|
|
31
|
-
new
|
|
32
|
-
super
|
|
33
|
-
package
|
|
34
|
-
throws
|
|
35
|
-
synchronized
|
|
36
|
-
volatile
|
|
37
|
-
transient
|
|
38
|
-
native
|
|
39
|
-
strictfp
|
|
40
|
-
override
|
|
41
|
-
# C / C++
|
|
42
|
-
unsigned
|
|
43
|
-
signed
|
|
44
|
-
typedef
|
|
45
|
-
sizeof
|
|
46
|
-
extern
|
|
47
|
-
register
|
|
48
|
-
restrict
|
|
49
|
-
inline
|
|
50
|
-
template
|
|
51
|
-
typename
|
|
52
|
-
virtual
|
|
53
|
-
friend
|
|
54
|
-
mutable
|
|
55
|
-
explicit
|
|
56
|
-
operator
|
|
57
|
-
typeid
|
|
58
|
-
# Rust
|
|
59
|
-
mut
|
|
60
|
-
fn
|
|
61
|
-
pub
|
|
62
|
-
mod
|
|
63
|
-
trait
|
|
64
|
-
impl
|
|
65
|
-
where
|
|
66
|
-
loop
|
|
67
|
-
unsafe
|
|
68
|
-
crate
|
|
69
|
-
dyn
|
|
70
|
-
# Go
|
|
71
|
-
func
|
|
72
|
-
chan
|
|
73
|
-
defer
|
|
74
|
-
fallthrough
|
|
75
|
-
goto
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|