3
3
import sys
4
4
import textwrap
5
5
from datetime import datetime
6
- from typing import Literal
6
+ from typing import Literal , Self
7
7
8
8
import tomlkit
9
9
from rich import print
@@ -40,6 +40,10 @@ def __init__(
40
40
# Wether this message should be printed on execution (will still print on resume, unlike hide)
41
41
self .quiet = quiet
42
42
43
+ def __repr__ (self ):
44
+ content = textwrap .shorten (self .content , 20 , placeholder = "..." )
45
+ return f"<Message role={ self .role } content={ content } >"
46
+
43
47
def to_dict (self , keys = None ):
44
48
"""Return a dict representation of the message, serializable to JSON."""
45
49
d = {
@@ -54,9 +58,48 @@ def to_dict(self, keys=None):
54
58
def format (self , oneline : bool = False , highlight : bool = False ) -> str :
55
59
return format_msgs ([self ], oneline = oneline , highlight = highlight )[0 ]
56
60
57
- def __repr__ (self ):
58
- content = textwrap .shorten (self .content , 20 , placeholder = "..." )
59
- return f"<Message role={ self .role } content={ content } >"
61
+ def to_toml (self ) -> str :
62
+ """Converts a message to a TOML string, for easy editing by hand in editor to then be parsed back."""
63
+ flags = []
64
+ if self .pinned :
65
+ flags .append ("pinned" )
66
+ if self .hide :
67
+ flags .append ("hide" )
68
+ if self .quiet :
69
+ flags .append ("quiet" )
70
+ flags_toml = "\n " .join (f"{ flag } = true" for flag in flags )
71
+
72
+ # doublequotes need to be escaped
73
+ content = self .content .replace ('"' , '\\ "' )
74
+ return f'''[message]
75
+ role = "{ self .role } "
76
+ content = """
77
+ { content }
78
+ """
79
+ timestamp = "{ self .timestamp .isoformat ()} "
80
+ { flags_toml }
81
+ '''
82
+
83
+ @classmethod
84
+ def from_toml (cls , toml : str ) -> Self :
85
+ """
86
+ Converts a TOML string to a message.
87
+
88
+ The string can be a single [[message]].
89
+ """
90
+
91
+ t = tomlkit .parse (toml )
92
+ assert "message" in t and isinstance (t ["message" ], dict )
93
+ msg : dict = t ["message" ] # type: ignore
94
+
95
+ return cls (
96
+ msg ["role" ],
97
+ msg ["content" ],
98
+ pinned = msg .get ("pinned" , False ),
99
+ hide = msg .get ("hide" , False ),
100
+ quiet = msg .get ("quiet" , False ),
101
+ timestamp = datetime .fromisoformat (msg ["timestamp" ]),
102
+ )
60
103
61
104
def get_codeblocks (self , content = False ) -> list [str ]:
62
105
"""
@@ -154,58 +197,15 @@ def print_msg(
154
197
)
155
198
156
199
157
- def msg_to_toml (msg : Message ) -> str :
158
- """Converts a message to a TOML string, for easy editing by hand in editor to then be parsed back."""
159
- # TODO: escape msg.content
160
- flags = []
161
- if msg .pinned :
162
- flags .append ("pinned" )
163
- if msg .hide :
164
- flags .append ("hide" )
165
- if msg .quiet :
166
- flags .append ("quiet" )
167
-
168
- # doublequotes need to be escaped
169
- content = msg .content .replace ('"' , '\\ "' )
170
- return f'''[message]
171
- role = "{ msg .role } "
172
- content = """
173
- { content }
174
- """
175
- timestamp = "{ msg .timestamp .isoformat ()} "
176
- '''
177
-
178
-
179
200
def msgs_to_toml (msgs : list [Message ]) -> str :
180
201
"""Converts a list of messages to a TOML string, for easy editing by hand in editor to then be parsed back."""
181
202
t = ""
182
203
for msg in msgs :
183
- t += msg_to_toml ( msg ).replace ("[message]" , "[[messages]]" ) + "\n \n "
204
+ t += msg . to_toml ( ).replace ("[message]" , "[[messages]]" ) + "\n \n "
184
205
185
206
return t
186
207
187
208
188
- def toml_to_msg (toml : str ) -> Message :
189
- """
190
- Converts a TOML string to a message.
191
-
192
- The string can be a single [[message]].
193
- """
194
-
195
- t = tomlkit .parse (toml )
196
- assert "message" in t and isinstance (t ["message" ], dict )
197
- msg : dict = t ["message" ] # type: ignore
198
-
199
- return Message (
200
- msg ["role" ],
201
- msg ["content" ],
202
- pinned = msg .get ("pinned" , False ),
203
- hide = msg .get ("hide" , False ),
204
- quiet = msg .get ("quiet" , False ),
205
- timestamp = datetime .fromisoformat (msg ["timestamp" ]),
206
- )
207
-
208
-
209
209
def toml_to_msgs (toml : str ) -> list [Message ]:
210
210
"""
211
211
Converts a TOML string to a list of messages.
0 commit comments