pylogue 0.2.1__py3-none-any.whl → 0.3__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.
pylogue/_modidx.py CHANGED
@@ -11,6 +11,7 @@ d = { 'settings': { 'branch': 'main',
11
11
  'pylogue.cards.ChatCard._get_role_style': ('0-card.html#chatcard._get_role_style', 'pylogue/cards.py'),
12
12
  'pylogue.cards.ChatCard._get_style': ('0-card.html#chatcard._get_style', 'pylogue/cards.py'),
13
13
  'pylogue.cards.ChatCard._get_text_color': ('0-card.html#chatcard._get_text_color', 'pylogue/cards.py'),
14
+ 'pylogue.cards.ChatCard.get_mobile_styles': ('0-card.html#chatcard.get_mobile_styles', 'pylogue/cards.py'),
14
15
  'pylogue.cards.ChatCard.render': ('0-card.html#chatcard.render', 'pylogue/cards.py'),
15
16
  'pylogue.cards.mk_inp': ('0-card.html#mk_inp', 'pylogue/cards.py'),
16
17
  'pylogue.cards.render_chat_list': ('0-card.html#render_chat_list', 'pylogue/cards.py')},
pylogue/cards.py CHANGED
@@ -14,18 +14,19 @@ class ChatCard:
14
14
  assistant_color: str = "#004539",
15
15
  user_emoji: str = "🗣️",
16
16
  assistant_emoji: str = "🕵️‍♂️",
17
- width: str = "60%",
17
+ max_width: str = "80%",
18
+ card_max_width: str = "60%",
18
19
  font_size: str = "1.5em",
20
+ mobile_font_size: str = "16px",
19
21
  padding: str = "1.25em",
20
- border_radius: str = "1em",
21
22
  user_align: str = "right",
22
23
  assistant_align: str = "left",
23
- user_self_align: str = "center",
24
- assistant_self_align: str = "center",
24
+ user_self_align: str = "flex-end",
25
+ assistant_self_align: str = "flex-start",
25
26
  role_font_weight: str = "bold",
26
27
  role_font_size: str = "1.1em",
27
28
  role_margin_bottom: str = "8px",
28
- content_white_space: str = "pre-wrap",
29
+ content_white_space: str = "normal",
29
30
  spinner_class: str = "spinner",
30
31
  ):
31
32
  self.colors = {
@@ -40,11 +41,14 @@ class ChatCard:
40
41
  "Assistant": {"text": assistant_align, "self": assistant_self_align},
41
42
  }
42
43
 
44
+ self.border_radii = {"User": "1em 1em 0em 1em", "Assistant": "1em 1em 1em 0em"}
45
+
43
46
  # Style configuration
44
- self.width = width
47
+ self.card_max_width = card_max_width
48
+ self.max_width = max_width
45
49
  self.font_size = font_size
50
+ self.mobile_font_size = mobile_font_size
46
51
  self.padding = padding
47
- self.border_radius = border_radius
48
52
  self.role_font_weight = role_font_weight
49
53
  self.role_font_size = role_font_size
50
54
  self.role_margin_bottom = role_margin_bottom
@@ -54,8 +58,8 @@ class ChatCard:
54
58
  # Build style template
55
59
  self.style_template = f"""
56
60
  background: {{bg}}; color: {{text_color}}; padding: 10px; font-size: {self.font_size};
57
- width: {self.width}; align-self: {{self_align}};
58
- text-align: {{text_align}}; border-radius: {self.border_radius};
61
+ max-width: min({self.card_max_width}, {self.max_width}); align-self: {{self_align}};
62
+ text-align: {{text_align}}; border-radius: {{border_radius}};
59
63
  padding: {self.padding}"""
60
64
 
61
65
  def _get_text_color(self, bg_color: str) -> str:
@@ -89,12 +93,23 @@ class ChatCard:
89
93
  text_color=self._get_text_color(bg_color),
90
94
  self_align=self.alignments[role]["self"],
91
95
  text_align=self.alignments[role]["text"],
96
+ border_radius=self.border_radii[role],
92
97
  )
93
98
 
94
99
  def _get_role_style(self) -> str:
95
100
  """Generate CSS style string for role labels."""
96
101
  return f"font-weight: {self.role_font_weight}; font-size: {self.role_font_size}; display: block; margin-bottom: {self.role_margin_bottom};"
97
102
 
103
+ def get_mobile_styles(self) -> str:
104
+ """Generate CSS media query for mobile devices."""
105
+ return f"""
106
+ @media (max-width: 768px) {{
107
+ .chat-card {{
108
+ font-size: {self.mobile_font_size} !important;
109
+ }}
110
+ }}
111
+ """
112
+
98
113
  def render(self, data: dict):
99
114
  """
100
115
  Render a chat card with the given data.
@@ -117,7 +132,7 @@ class ChatCard:
117
132
 
118
133
  if pending:
119
134
  spinner = Span(cls=self.spinner_class)
120
- return Div(f"{emoji} {role}: ", spinner, style=style)
135
+ return Div(f"{emoji} {role}: ", spinner, style=style, cls="chat-card")
121
136
 
122
137
  # Add 'marked' class to enable markdown rendering
123
138
  return Div(
@@ -129,6 +144,7 @@ class ChatCard:
129
144
  content, cls="marked", style=f"white-space: {self.content_white_space};"
130
145
  ),
131
146
  style=style,
147
+ cls="chat-card",
132
148
  )
133
149
 
134
150
  def __call__(self, data: dict):
@@ -141,6 +157,7 @@ CHAT_DIV_ID = "chat-cards"
141
157
 
142
158
  def render_chat_list(messages: List[Dict[str, str]], ChatCard: ChatCard):
143
159
  return Div(
160
+ Style(ChatCard.get_mobile_styles()),
144
161
  *[ChatCard(m) for m in messages],
145
162
  id=CHAT_DIV_ID,
146
163
  cls="chat-cards",
pylogue/chatapp.py CHANGED
@@ -121,6 +121,9 @@ class ChatApp:
121
121
  # Add spinner styles
122
122
  headers.append(Style(self.config.get_spinner_style()))
123
123
 
124
+ # Add mobile responsive styles from ChatCard
125
+ headers.append(Style(self.renderer.card.get_mobile_styles()))
126
+
124
127
  return FastHTML(exts="ws", hdrs=tuple(headers))
125
128
 
126
129
  def _get_initial_messages(self) -> List[Message]:
@@ -133,22 +136,24 @@ class ChatApp:
133
136
  """Register HTTP and WebSocket routes."""
134
137
 
135
138
  @self.app.route(self.config.chat_endpoint)
136
- def home():
139
+ def chat():
137
140
  """Main chat interface."""
138
141
  initial_messages = self._get_initial_messages()
139
142
 
140
143
  container_style = self.config.container_style or (
141
144
  f"font-family: monospace, sans-serif; margin: 0; padding: 0; "
142
- f"background: {self.config.bg_color}; min-height: 100vh;"
143
145
  )
144
146
 
145
147
  return (
146
148
  Title(self.config.page_title),
147
- Div(
148
- H1(self.config.app_title, style=self.config.header_style),
149
- self.renderer.render_messages(initial_messages),
150
- self.renderer.render_form(),
151
- style=container_style,
149
+ Body(
150
+ Div(
151
+ H1(self.config.app_title, style=self.config.header_style),
152
+ self.renderer.render_messages(initial_messages),
153
+ self.renderer.render_form(),
154
+ style=container_style,
155
+ ),
156
+ style="background-color: #000",
152
157
  ),
153
158
  )
154
159
 
@@ -211,7 +216,7 @@ class ChatApp:
211
216
  assistant_msg.id, content=full_response, pending=False
212
217
  )
213
218
  # Send updated message list to UI
214
- print(f"📤 Sending chunk #{chunk_count}: {repr(chunk)}") # Debug
219
+ # print(f"📤 Sending chunk #{chunk_count}: {repr(chunk)}") # Debug
215
220
  await send(self.renderer.render_messages(session.get_messages()))
216
221
 
217
222
  except Exception as e:
pylogue/renderer.py CHANGED
@@ -41,7 +41,7 @@ class ChatRenderer:
41
41
  "font-size: 1em; border-radius: 0.5em"
42
42
  )
43
43
  self.chat_container_style = chat_container_style or (
44
- "display: flex; flex-direction: column; gap: 10px;"
44
+ "display: flex; flex-direction: column; gap: 1em; margin: 3em;"
45
45
  )
46
46
 
47
47
  def render_message(self, message: Message) -> Any:
@@ -58,7 +58,18 @@ class ChatRenderer:
58
58
  Returns:
59
59
  FastHTML Div containing all rendered messages
60
60
  """
61
+ # Add mobile-responsive margin CSS
62
+ mobile_margin_css = """
63
+ @media (max-width: 768px) {
64
+ .chat-cards {
65
+ margin: 1em !important;
66
+ }
67
+ }
68
+ """
69
+
61
70
  return Div(
71
+ Style(self.card.get_mobile_styles()),
72
+ Style(mobile_margin_css),
62
73
  *[self.render_message(msg) for msg in messages],
63
74
  id=self.CHAT_DIV_ID,
64
75
  cls="chat-cards",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pylogue
3
- Version: 0.2.1
3
+ Version: 0.3
4
4
  Summary: A Chatbot UI built for AI agents
5
5
  Author-email: Yeshwanth Reddy <yyeshr@gmail.com>
6
6
  Maintainer-email: Yeshwanth Reddy <yyeshr@gmail.com>
@@ -0,0 +1,17 @@
1
+ pylogue/__init__.py,sha256=gDXS44jmg6hPtcg8IxTFRdyV-TGsjQTkT-5NjiapYZ4,319
2
+ pylogue/__pre_init__.py,sha256=NiQUAz7feHFR47QTpMwF324j61IVrOreZsk9wY11cds,153
3
+ pylogue/_modidx.py,sha256=IDAxgZ4opfun-D1eJ9qH1F0gvv-y5OzXlEDhak8BG30,14348
4
+ pylogue/cards.py,sha256=iu8fgkE2WLERAeawna5AY4-0_KqWhDGQ9NSj4Cygp2w,6041
5
+ pylogue/chat.py,sha256=RyRADCZWxTjCM3W7FgIj0jQ8WrqhRBzbeFEvS9mTZq4,3982
6
+ pylogue/chatapp.py,sha256=Pnpr4PR2qI8oHvTLynMr2n2DaCerEJeBSRMy7MF4AXs,10142
7
+ pylogue/health.py,sha256=8LWhpVzdj2g6qUcErrg455_6WfOsv3lp82OLLwJPtug,443
8
+ pylogue/renderer.py,sha256=nkFsSNiqMj98n3kPyLu77PnyiGBPLOXNvmXRb7-JQF8,4176
9
+ pylogue/service.py,sha256=e3GfbQrOPlRIj7j0CZZx_qN2ZI_polOuWqBMm7ySXqs,6917
10
+ pylogue/session.py,sha256=fUyGOFIG8b1clhyyw5c_dapdwrJyzd9K2bOc_qKBQcs,5382
11
+ pylogue-0.3.dist-info/licenses/AUTHORS.md,sha256=5Viska6TOr9uggc2olSr8VVnu6BFw_F6_64gP42CwQ4,157
12
+ pylogue-0.3.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ pylogue-0.3.dist-info/METADATA,sha256=GQDIfcrpAg9CUiAkcSAsn6BhmTisLmuVqu0H_dUQ84M,1057
14
+ pylogue-0.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
+ pylogue-0.3.dist-info/entry_points.txt,sha256=ha0gwcGgtciKEhmFcMKJO1efTY9Spu1wcTHUopB1bec,40
16
+ pylogue-0.3.dist-info/top_level.txt,sha256=oEueWVdlRAUPQt8VfQdqFEqOWxvUObx3UIa3UYa3s6o,8
17
+ pylogue-0.3.dist-info/RECORD,,
@@ -1,17 +0,0 @@
1
- pylogue/__init__.py,sha256=gDXS44jmg6hPtcg8IxTFRdyV-TGsjQTkT-5NjiapYZ4,319
2
- pylogue/__pre_init__.py,sha256=NiQUAz7feHFR47QTpMwF324j61IVrOreZsk9wY11cds,153
3
- pylogue/_modidx.py,sha256=apvAlYvaQgShSh_ZrX7fXSpxDdwPBYIKwEQWdEkVJg8,14209
4
- pylogue/cards.py,sha256=wsOVNbMczFbyoATkujC7xJAeskYgTqsJmxmkHqzHA-g,5385
5
- pylogue/chat.py,sha256=RyRADCZWxTjCM3W7FgIj0jQ8WrqhRBzbeFEvS9mTZq4,3982
6
- pylogue/chatapp.py,sha256=Rn2GMmo7GTatsnAdIuYFTalLMb9qTxS1BmikQUVlE3Y,9973
7
- pylogue/health.py,sha256=8LWhpVzdj2g6qUcErrg455_6WfOsv3lp82OLLwJPtug,443
8
- pylogue/renderer.py,sha256=KGo0l-Jo8i2pe8NqwlZsM9Qo3ZBA2EV-osrHnBUWzBA,3862
9
- pylogue/service.py,sha256=e3GfbQrOPlRIj7j0CZZx_qN2ZI_polOuWqBMm7ySXqs,6917
10
- pylogue/session.py,sha256=fUyGOFIG8b1clhyyw5c_dapdwrJyzd9K2bOc_qKBQcs,5382
11
- pylogue-0.2.1.dist-info/licenses/AUTHORS.md,sha256=5Viska6TOr9uggc2olSr8VVnu6BFw_F6_64gP42CwQ4,157
12
- pylogue-0.2.1.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- pylogue-0.2.1.dist-info/METADATA,sha256=efMS8zmtNQAeAlcthiuk8oxhkTh5OeYn6Z7kF-ft_vg,1059
14
- pylogue-0.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
- pylogue-0.2.1.dist-info/entry_points.txt,sha256=ha0gwcGgtciKEhmFcMKJO1efTY9Spu1wcTHUopB1bec,40
16
- pylogue-0.2.1.dist-info/top_level.txt,sha256=oEueWVdlRAUPQt8VfQdqFEqOWxvUObx3UIa3UYa3s6o,8
17
- pylogue-0.2.1.dist-info/RECORD,,
File without changes