lionagi 0.13.0__py3-none-any.whl → 0.13.2__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.
- lionagi/_errors.py +4 -0
- lionagi/libs/schema/as_readable.py +224 -2
- lionagi/models/field_model.py +645 -174
- lionagi/models/model_params.py +17 -8
- lionagi/models/operable_model.py +4 -2
- lionagi/protocols/operatives/operative.py +205 -36
- lionagi/protocols/operatives/step.py +2 -1
- lionagi/service/connections/providers/claude_code_.py +194 -20
- lionagi/service/connections/providers/oai_.py +1 -13
- lionagi/traits/__init__.py +58 -0
- lionagi/traits/base.py +216 -0
- lionagi/traits/composer.py +343 -0
- lionagi/traits/protocols.py +495 -0
- lionagi/traits/registry.py +1071 -0
- lionagi/version.py +1 -1
- {lionagi-0.13.0.dist-info → lionagi-0.13.2.dist-info}/METADATA +9 -2
- {lionagi-0.13.0.dist-info → lionagi-0.13.2.dist-info}/RECORD +19 -14
- {lionagi-0.13.0.dist-info → lionagi-0.13.2.dist-info}/WHEEL +0 -0
- {lionagi-0.13.0.dist-info → lionagi-0.13.2.dist-info}/licenses/LICENSE +0 -0
lionagi/_errors.py
CHANGED
@@ -3,10 +3,90 @@
|
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
5
|
import json
|
6
|
+
import sys
|
6
7
|
from typing import Any
|
7
8
|
|
8
9
|
from lionagi.utils import to_dict
|
9
10
|
|
11
|
+
# Try to import rich for enhanced console output
|
12
|
+
try:
|
13
|
+
from rich.align import Align
|
14
|
+
from rich.box import ROUNDED
|
15
|
+
from rich.console import Console
|
16
|
+
from rich.padding import Padding
|
17
|
+
from rich.panel import Panel
|
18
|
+
from rich.syntax import Syntax
|
19
|
+
from rich.theme import Theme
|
20
|
+
|
21
|
+
RICH_AVAILABLE = True
|
22
|
+
except ImportError:
|
23
|
+
RICH_AVAILABLE = False
|
24
|
+
|
25
|
+
# Custom themes for dark and light modes
|
26
|
+
DARK_THEME = Theme(
|
27
|
+
{
|
28
|
+
"info": "bright_cyan",
|
29
|
+
"warning": "bright_yellow",
|
30
|
+
"error": "bold bright_red",
|
31
|
+
"success": "bold bright_green",
|
32
|
+
"panel.border": "bright_blue",
|
33
|
+
"panel.title": "bold bright_cyan",
|
34
|
+
"markdown.h1": "bold bright_magenta",
|
35
|
+
"markdown.h2": "bold bright_blue",
|
36
|
+
"markdown.h3": "bold bright_cyan",
|
37
|
+
"markdown.h4": "bold bright_green",
|
38
|
+
"markdown.code": "bright_yellow on grey23",
|
39
|
+
"markdown.code_block": "bright_white on grey15",
|
40
|
+
"markdown.paragraph": "bright_white",
|
41
|
+
"markdown.text": "bright_white",
|
42
|
+
"markdown.emph": "italic bright_yellow",
|
43
|
+
"markdown.strong": "bold bright_white",
|
44
|
+
"markdown.item": "bright_cyan",
|
45
|
+
"markdown.item.bullet": "bright_blue",
|
46
|
+
"json.key": "bright_cyan",
|
47
|
+
"json.string": "bright_green",
|
48
|
+
"json.number": "bright_yellow",
|
49
|
+
"json.boolean": "bright_magenta",
|
50
|
+
"json.null": "bright_red",
|
51
|
+
"yaml.key": "bright_cyan",
|
52
|
+
"yaml.string": "bright_green",
|
53
|
+
"yaml.number": "bright_yellow",
|
54
|
+
"yaml.boolean": "bright_magenta",
|
55
|
+
}
|
56
|
+
)
|
57
|
+
|
58
|
+
LIGHT_THEME = Theme(
|
59
|
+
{
|
60
|
+
"info": "blue",
|
61
|
+
"warning": "dark_orange",
|
62
|
+
"error": "bold red",
|
63
|
+
"success": "bold green4",
|
64
|
+
"panel.border": "blue",
|
65
|
+
"panel.title": "bold blue",
|
66
|
+
"markdown.h1": "bold dark_magenta",
|
67
|
+
"markdown.h2": "bold dark_blue",
|
68
|
+
"markdown.h3": "bold dark_cyan",
|
69
|
+
"markdown.h4": "bold dark_green",
|
70
|
+
"markdown.code": "dark_orange on grey93",
|
71
|
+
"markdown.code_block": "black on grey82",
|
72
|
+
"markdown.paragraph": "black",
|
73
|
+
"markdown.text": "black",
|
74
|
+
"markdown.emph": "italic dark_orange",
|
75
|
+
"markdown.strong": "bold black",
|
76
|
+
"markdown.item": "dark_blue",
|
77
|
+
"markdown.item.bullet": "blue",
|
78
|
+
"json.key": "dark_blue",
|
79
|
+
"json.string": "dark_green",
|
80
|
+
"json.number": "dark_orange",
|
81
|
+
"json.boolean": "dark_magenta",
|
82
|
+
"json.null": "dark_red",
|
83
|
+
"yaml.key": "dark_blue",
|
84
|
+
"yaml.string": "dark_green",
|
85
|
+
"yaml.number": "dark_orange",
|
86
|
+
"yaml.boolean": "dark_magenta",
|
87
|
+
}
|
88
|
+
)
|
89
|
+
|
10
90
|
|
11
91
|
def in_notebook() -> bool:
|
12
92
|
"""
|
@@ -22,6 +102,18 @@ def in_notebook() -> bool:
|
|
22
102
|
return False
|
23
103
|
|
24
104
|
|
105
|
+
def in_console() -> bool:
|
106
|
+
"""
|
107
|
+
Checks if we're running in a console/terminal environment.
|
108
|
+
Returns True if stdout is a TTY and not in a notebook.
|
109
|
+
"""
|
110
|
+
return (
|
111
|
+
hasattr(sys.stdout, "isatty")
|
112
|
+
and sys.stdout.isatty()
|
113
|
+
and not in_notebook()
|
114
|
+
)
|
115
|
+
|
116
|
+
|
25
117
|
def format_dict(data: Any, indent: int = 0) -> str:
|
26
118
|
"""
|
27
119
|
Recursively format Python data (dicts, lists, strings, etc.) into a
|
@@ -77,6 +169,9 @@ def as_readable(
|
|
77
169
|
format_curly: bool = False,
|
78
170
|
display_str: bool = False,
|
79
171
|
max_chars: int | None = None,
|
172
|
+
use_rich: bool = True,
|
173
|
+
theme: str = "dark",
|
174
|
+
max_panel_width: int = 140,
|
80
175
|
) -> str:
|
81
176
|
"""
|
82
177
|
Convert `input_` into a human-readable string. If `format_curly=True`, uses
|
@@ -84,14 +179,21 @@ def as_readable(
|
|
84
179
|
|
85
180
|
- For Pydantic models or nested data, uses `to_dict` to get a dictionary.
|
86
181
|
- If the result is a list of items, each is processed and concatenated.
|
182
|
+
- When in console and rich is available, provides syntax highlighting.
|
87
183
|
|
88
184
|
Args:
|
89
185
|
input_: The data to convert (could be a single item or list).
|
90
186
|
md: If True, wraps the final output in code fences for Markdown display.
|
91
187
|
format_curly: If True, use `format_dict`. Otherwise, produce JSON text.
|
188
|
+
display_str: If True, prints the output instead of returning it.
|
189
|
+
max_chars: If set, truncates output to this many characters.
|
190
|
+
use_rich: If True and rich is available, uses rich for console output.
|
191
|
+
theme: Color theme - "dark" (default) or "light". Dark uses GitHub Dark Dimmed,
|
192
|
+
light uses Solarized Light inspired colors.
|
193
|
+
max_panel_width: Maximum width for panels and code blocks in characters.
|
92
194
|
|
93
195
|
Returns:
|
94
|
-
A formatted string representation of `input_
|
196
|
+
A formatted string representation of `input_` (unless display_str=True).
|
95
197
|
"""
|
96
198
|
|
97
199
|
# 1) Convert the input to a Python dict/list structure
|
@@ -108,6 +210,7 @@ def as_readable(
|
|
108
210
|
return to_dict(obj, **to_dict_kwargs)
|
109
211
|
|
110
212
|
def _inner(i_: Any) -> Any:
|
213
|
+
items = []
|
111
214
|
try:
|
112
215
|
if isinstance(i_, list):
|
113
216
|
# Already a list. Convert each item
|
@@ -167,8 +270,127 @@ def as_readable(
|
|
167
270
|
from IPython.display import Markdown, display
|
168
271
|
|
169
272
|
display(Markdown(str_))
|
273
|
+
elif RICH_AVAILABLE and in_console() and use_rich:
|
274
|
+
# Use rich for enhanced console output
|
275
|
+
# Select theme and syntax highlighting based on user preference
|
276
|
+
console_theme = DARK_THEME if theme == "dark" else LIGHT_THEME
|
277
|
+
syntax_theme = (
|
278
|
+
"github-dark" if theme == "dark" else "solarized-light"
|
279
|
+
)
|
280
|
+
panel_style = "bright_blue" if theme == "dark" else "blue"
|
281
|
+
|
282
|
+
console = Console(theme=console_theme)
|
283
|
+
|
284
|
+
# Check if content looks like markdown prose (not code)
|
285
|
+
is_markdown_prose = isinstance(str_, str) and (
|
286
|
+
str_.startswith("#")
|
287
|
+
or str_.startswith("**")
|
288
|
+
or str_.startswith("- ")
|
289
|
+
or str_.startswith("1.")
|
290
|
+
or "<multi_reasoning>" in str_
|
291
|
+
or "\n### " in str_
|
292
|
+
or "\n## " in str_
|
293
|
+
or "\n# " in str_
|
294
|
+
or "│" in str_ # Rich table content
|
295
|
+
)
|
296
|
+
|
297
|
+
if md and is_markdown_prose:
|
298
|
+
# Display as formatted markdown
|
299
|
+
# Create markdown with max width
|
300
|
+
from rich.markdown import Markdown as RichMarkdown
|
301
|
+
|
302
|
+
md_content = RichMarkdown(str_, code_theme=syntax_theme)
|
303
|
+
|
304
|
+
# Calculate appropriate width
|
305
|
+
console_width = console.width
|
306
|
+
panel_width = min(console_width - 4, max_panel_width)
|
307
|
+
|
308
|
+
# Add left margin padding for better alignment
|
309
|
+
panel = Panel(
|
310
|
+
Padding(md_content, (0, 2)),
|
311
|
+
border_style=panel_style,
|
312
|
+
box=ROUNDED,
|
313
|
+
width=panel_width,
|
314
|
+
expand=False,
|
315
|
+
)
|
316
|
+
|
317
|
+
# Left align with margin
|
318
|
+
aligned_panel = Align.left(panel, pad=True)
|
319
|
+
console.print(Padding(aligned_panel, (0, 0, 0, 4)))
|
320
|
+
|
321
|
+
elif md:
|
322
|
+
# Extract content from markdown code blocks if present
|
323
|
+
content = str_
|
324
|
+
if content.startswith("```") and content.endswith("```"):
|
325
|
+
# Remove code fences
|
326
|
+
lines = content.split("\n")
|
327
|
+
if len(lines) > 2:
|
328
|
+
lang = lines[0][3:].strip() or "json"
|
329
|
+
content = "\n".join(lines[1:-1])
|
330
|
+
else:
|
331
|
+
lang = "json"
|
332
|
+
else:
|
333
|
+
lang = "yaml" if format_curly else "json"
|
334
|
+
|
335
|
+
# Calculate appropriate width
|
336
|
+
console_width = console.width
|
337
|
+
panel_width = min(console_width - 4, max_panel_width)
|
338
|
+
|
339
|
+
# Create syntax highlighted output
|
340
|
+
syntax = Syntax(
|
341
|
+
content,
|
342
|
+
lang,
|
343
|
+
theme=syntax_theme,
|
344
|
+
line_numbers=True,
|
345
|
+
background_color="default",
|
346
|
+
word_wrap=True,
|
347
|
+
)
|
348
|
+
|
349
|
+
# Add left margin padding for better alignment
|
350
|
+
panel = Panel(
|
351
|
+
syntax,
|
352
|
+
border_style=panel_style,
|
353
|
+
box=ROUNDED,
|
354
|
+
width=panel_width,
|
355
|
+
expand=False,
|
356
|
+
)
|
357
|
+
|
358
|
+
# Left align with margin
|
359
|
+
aligned_panel = Align.left(panel, pad=True)
|
360
|
+
console.print(Padding(aligned_panel, (0, 0, 0, 4)))
|
361
|
+
|
362
|
+
else:
|
363
|
+
# Plain text output with rich formatting
|
364
|
+
if format_curly:
|
365
|
+
syntax = Syntax(
|
366
|
+
str_,
|
367
|
+
"yaml",
|
368
|
+
theme=syntax_theme,
|
369
|
+
background_color="default",
|
370
|
+
word_wrap=True,
|
371
|
+
)
|
372
|
+
else:
|
373
|
+
syntax = Syntax(
|
374
|
+
str_,
|
375
|
+
"json",
|
376
|
+
theme=syntax_theme,
|
377
|
+
background_color="default",
|
378
|
+
word_wrap=True,
|
379
|
+
)
|
380
|
+
|
381
|
+
# For plain syntax, add left margin
|
382
|
+
# Create a constrained width container if console is too wide
|
383
|
+
if console.width > max_panel_width:
|
384
|
+
content = Align.left(
|
385
|
+
syntax, width=max_panel_width, pad=False
|
386
|
+
)
|
387
|
+
# Add left margin
|
388
|
+
console.print(Padding(content, (0, 0, 0, 4)))
|
389
|
+
else:
|
390
|
+
# Just add left margin
|
391
|
+
console.print(Padding(syntax, (0, 0, 0, 4)))
|
170
392
|
else:
|
171
|
-
#
|
393
|
+
# Fallback to regular print
|
172
394
|
print(str_)
|
173
395
|
else:
|
174
396
|
return str_
|