lionagi 0.13.2__py3-none-any.whl → 0.13.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.
- lionagi/fields/action.py +0 -1
- lionagi/fields/reason.py +0 -1
- lionagi/libs/file/save.py +1 -1
- lionagi/libs/schema/as_readable.py +142 -196
- lionagi/libs/schema/extract_docstring.py +1 -2
- lionagi/libs/token_transform/synthlang_/base.py +0 -2
- lionagi/libs/validate/string_similarity.py +1 -2
- lionagi/models/hashable_model.py +0 -1
- lionagi/models/schema_model.py +0 -1
- lionagi/operations/ReAct/utils.py +0 -1
- lionagi/operations/_act/act.py +0 -1
- lionagi/operations/interpret/interpret.py +1 -4
- lionagi/operations/manager.py +0 -1
- lionagi/operations/plan/plan.py +0 -1
- lionagi/operations/select/utils.py +0 -2
- lionagi/protocols/forms/flow.py +3 -1
- lionagi/protocols/generic/pile.py +1 -2
- lionagi/protocols/generic/processor.py +0 -1
- lionagi/protocols/graph/graph.py +1 -3
- lionagi/protocols/mail/package.py +0 -1
- lionagi/protocols/messages/assistant_response.py +0 -2
- lionagi/protocols/messages/message.py +0 -1
- lionagi/service/connections/endpoint_config.py +6 -0
- lionagi/service/connections/match_endpoint.py +26 -8
- lionagi/service/connections/providers/claude_code_.py +8 -9
- lionagi/service/connections/providers/claude_code_cli.py +414 -0
- lionagi/service/connections/providers/oai_.py +1 -1
- lionagi/service/manager.py +0 -1
- lionagi/service/rate_limited_processor.py +0 -2
- lionagi/service/token_calculator.py +0 -3
- lionagi/session/branch.py +0 -2
- lionagi/session/session.py +0 -1
- lionagi/settings.py +0 -1
- lionagi/utils.py +6 -9
- lionagi/version.py +1 -1
- {lionagi-0.13.2.dist-info → lionagi-0.13.3.dist-info}/METADATA +5 -3
- {lionagi-0.13.2.dist-info → lionagi-0.13.3.dist-info}/RECORD +39 -43
- lionagi/traits/__init__.py +0 -58
- lionagi/traits/base.py +0 -216
- lionagi/traits/composer.py +0 -343
- lionagi/traits/protocols.py +0 -495
- lionagi/traits/registry.py +0 -1071
- {lionagi-0.13.2.dist-info → lionagi-0.13.3.dist-info}/WHEEL +0 -0
- {lionagi-0.13.2.dist-info → lionagi-0.13.3.dist-info}/licenses/LICENSE +0 -0
lionagi/fields/action.py
CHANGED
lionagi/fields/reason.py
CHANGED
lionagi/libs/file/save.py
CHANGED
@@ -11,81 +11,84 @@ from lionagi.utils import to_dict
|
|
11
11
|
# Try to import rich for enhanced console output
|
12
12
|
try:
|
13
13
|
from rich.align import Align
|
14
|
-
from rich.box import ROUNDED
|
14
|
+
from rich.box import MINIMAL, ROUNDED
|
15
15
|
from rich.console import Console
|
16
|
+
from rich.markdown import Markdown
|
16
17
|
from rich.padding import Padding
|
17
18
|
from rich.panel import Panel
|
19
|
+
from rich.style import Style
|
18
20
|
from rich.syntax import Syntax
|
21
|
+
from rich.text import Text
|
19
22
|
from rich.theme import Theme
|
20
23
|
|
24
|
+
DARK_THEME = Theme(
|
25
|
+
{
|
26
|
+
"info": "bright_cyan",
|
27
|
+
"warning": "bright_yellow",
|
28
|
+
"error": "bold bright_red",
|
29
|
+
"success": "bold bright_green",
|
30
|
+
"panel.border": "bright_blue",
|
31
|
+
"panel.title": "bold bright_cyan",
|
32
|
+
"markdown.h1": "bold bright_magenta",
|
33
|
+
"markdown.h2": "bold bright_blue",
|
34
|
+
"markdown.h3": "bold bright_cyan",
|
35
|
+
"markdown.h4": "bold bright_green",
|
36
|
+
"markdown.code": "bright_yellow on grey23",
|
37
|
+
"markdown.code_block": "bright_white on grey15",
|
38
|
+
"markdown.paragraph": "bright_white",
|
39
|
+
"markdown.text": "bright_white",
|
40
|
+
"markdown.emph": "italic bright_yellow",
|
41
|
+
"markdown.strong": "bold bright_white",
|
42
|
+
"markdown.item": "bright_cyan",
|
43
|
+
"markdown.item.bullet": "bright_blue",
|
44
|
+
"json.key": "bright_cyan",
|
45
|
+
"json.string": "bright_green",
|
46
|
+
"json.number": "bright_yellow",
|
47
|
+
"json.boolean": "bright_magenta",
|
48
|
+
"json.null": "bright_red",
|
49
|
+
"yaml.key": "bright_cyan",
|
50
|
+
"yaml.string": "bright_green",
|
51
|
+
"yaml.number": "bright_yellow",
|
52
|
+
"yaml.boolean": "bright_magenta",
|
53
|
+
}
|
54
|
+
)
|
55
|
+
|
56
|
+
LIGHT_THEME = Theme(
|
57
|
+
{
|
58
|
+
"info": "blue",
|
59
|
+
"warning": "dark_orange",
|
60
|
+
"error": "bold red",
|
61
|
+
"success": "bold green4",
|
62
|
+
"panel.border": "blue",
|
63
|
+
"panel.title": "bold blue",
|
64
|
+
"markdown.h1": "bold dark_magenta",
|
65
|
+
"markdown.h2": "bold dark_blue",
|
66
|
+
"markdown.h3": "bold dark_cyan",
|
67
|
+
"markdown.h4": "bold dark_green",
|
68
|
+
"markdown.code": "dark_orange on grey93",
|
69
|
+
"markdown.code_block": "black on grey82",
|
70
|
+
"markdown.paragraph": "black",
|
71
|
+
"markdown.text": "black",
|
72
|
+
"markdown.emph": "italic dark_orange",
|
73
|
+
"markdown.strong": "bold black",
|
74
|
+
"markdown.item": "dark_blue",
|
75
|
+
"markdown.item.bullet": "blue",
|
76
|
+
"json.key": "dark_blue",
|
77
|
+
"json.string": "dark_green",
|
78
|
+
"json.number": "dark_orange",
|
79
|
+
"json.boolean": "dark_magenta",
|
80
|
+
"json.null": "dark_red",
|
81
|
+
"yaml.key": "dark_blue",
|
82
|
+
"yaml.string": "dark_green",
|
83
|
+
"yaml.number": "dark_orange",
|
84
|
+
"yaml.boolean": "dark_magenta",
|
85
|
+
}
|
86
|
+
)
|
21
87
|
RICH_AVAILABLE = True
|
22
88
|
except ImportError:
|
23
89
|
RICH_AVAILABLE = False
|
24
|
-
|
25
|
-
|
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
|
-
)
|
90
|
+
DARK_THEME = None
|
91
|
+
LIGHT_THEME = None
|
89
92
|
|
90
93
|
|
91
94
|
def in_notebook() -> bool:
|
@@ -172,6 +175,8 @@ def as_readable(
|
|
172
175
|
use_rich: bool = True,
|
173
176
|
theme: str = "dark",
|
174
177
|
max_panel_width: int = 140,
|
178
|
+
panel: bool = True,
|
179
|
+
border: bool = True,
|
175
180
|
) -> str:
|
176
181
|
"""
|
177
182
|
Convert `input_` into a human-readable string. If `format_curly=True`, uses
|
@@ -191,6 +196,7 @@ def as_readable(
|
|
191
196
|
theme: Color theme - "dark" (default) or "light". Dark uses GitHub Dark Dimmed,
|
192
197
|
light uses Solarized Light inspired colors.
|
193
198
|
max_panel_width: Maximum width for panels and code blocks in characters.
|
199
|
+
panel: If True, wraps the output in a panel for better visibility.
|
194
200
|
|
195
201
|
Returns:
|
196
202
|
A formatted string representation of `input_` (unless display_str=True).
|
@@ -249,7 +255,6 @@ def as_readable(
|
|
249
255
|
final_str = "\n\n".join(rendered).strip()
|
250
256
|
|
251
257
|
# 4) If Markdown requested, wrap with code fences
|
252
|
-
# - If we used format_curly, we might do "```yaml" instead. But user specifically asked for JSON code blocks previously
|
253
258
|
if md:
|
254
259
|
if format_curly:
|
255
260
|
return f"```yaml\n{final_str}\n```"
|
@@ -260,137 +265,78 @@ def as_readable(
|
|
260
265
|
|
261
266
|
str_ = _inner(input_).strip()
|
262
267
|
if max_chars is not None and len(str_) > max_chars:
|
263
|
-
|
264
|
-
if str_.endswith("\n```")
|
265
|
-
|
266
|
-
|
267
|
-
if display_str:
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
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,
|
268
|
+
trunc = str_[:max_chars] + "...\n\n[Truncated output]"
|
269
|
+
str_ = trunc + ("\n```" if str_.endswith("\n```") else "")
|
270
|
+
|
271
|
+
# -------------------- PRINT / DISPLAY LOGIC ---------------------------
|
272
|
+
if not display_str:
|
273
|
+
return str_ # caller will handle printing
|
274
|
+
|
275
|
+
# (1) IPython notebook --------------------------------------------------
|
276
|
+
if md and in_notebook():
|
277
|
+
from IPython.display import Markdown, display
|
278
|
+
|
279
|
+
display(Markdown(str_))
|
280
|
+
return
|
281
|
+
|
282
|
+
# (2) Rich console ------------------------------------------------------
|
283
|
+
if RICH_AVAILABLE and in_console() and use_rich:
|
284
|
+
console_theme = DARK_THEME if theme == "dark" else LIGHT_THEME
|
285
|
+
syntax_theme = "github-dark" if theme == "dark" else "solarized-light"
|
286
|
+
console = Console(theme=console_theme)
|
287
|
+
|
288
|
+
# determine prose / fenced code
|
289
|
+
is_fenced_code = (
|
290
|
+
md and str_.startswith("```") and str_.rstrip().endswith("```")
|
291
|
+
)
|
292
|
+
is_prose_md = md and not is_fenced_code
|
293
|
+
panel_width = min(console.width - 4, max_panel_width)
|
294
|
+
|
295
|
+
def _out(rich_obj):
|
296
|
+
if not panel:
|
297
|
+
console.print(Padding(rich_obj, (0, 0, 0, 2)))
|
298
|
+
return
|
299
|
+
|
300
|
+
console.print(
|
301
|
+
Padding(
|
302
|
+
Panel(
|
303
|
+
Align.left(rich_obj, pad=False),
|
304
|
+
border_style="panel.border" if border else "",
|
305
|
+
box=ROUNDED if border else MINIMAL,
|
306
|
+
width=panel_width,
|
307
|
+
expand=False,
|
308
|
+
),
|
309
|
+
(0, 0, 0, 4),
|
347
310
|
)
|
311
|
+
)
|
348
312
|
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
border_style=panel_style,
|
353
|
-
box=ROUNDED,
|
354
|
-
width=panel_width,
|
355
|
-
expand=False,
|
356
|
-
)
|
313
|
+
# 2‑a prose markdown ------------------------------------------------
|
314
|
+
if is_prose_md:
|
315
|
+
from rich.markdown import Markdown as RichMarkdown
|
357
316
|
|
358
|
-
|
359
|
-
|
360
|
-
console.print(Padding(aligned_panel, (0, 0, 0, 4)))
|
317
|
+
_out(RichMarkdown(str_, code_theme=syntax_theme))
|
318
|
+
return
|
361
319
|
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
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)))
|
320
|
+
# 2‑b code (fenced or explicit) -------------------------------------
|
321
|
+
if is_fenced_code:
|
322
|
+
lines = str_.splitlines()
|
323
|
+
lang, code = (
|
324
|
+
(lines[0][3:].strip() or ("yaml" if format_curly else "json")),
|
325
|
+
"\n".join(lines[1:-1]),
|
326
|
+
)
|
392
327
|
else:
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
328
|
+
lang, code = ("yaml" if format_curly else "json"), str_
|
329
|
+
|
330
|
+
syntax = Syntax(
|
331
|
+
code,
|
332
|
+
lang,
|
333
|
+
theme=syntax_theme,
|
334
|
+
line_numbers=False,
|
335
|
+
word_wrap=True,
|
336
|
+
background_color="default",
|
337
|
+
)
|
338
|
+
_out(syntax)
|
339
|
+
return
|
340
|
+
|
341
|
+
# (3) Plain fallback ----------------------------------------------------
|
342
|
+
print(str_)
|
@@ -52,8 +52,7 @@ def extract_docstring(
|
|
52
52
|
)
|
53
53
|
else:
|
54
54
|
raise ValueError(
|
55
|
-
f'{style} is not supported. Please choose either "google" or'
|
56
|
-
' "reST".'
|
55
|
+
f'{style} is not supported. Please choose either "google" or "reST".'
|
57
56
|
)
|
58
57
|
return func_description, params_description
|
59
58
|
|
@@ -21,7 +21,6 @@ __all__ = (
|
|
21
21
|
|
22
22
|
|
23
23
|
class SynthlangFramework(Resource):
|
24
|
-
|
25
24
|
category: ResourceCategory = Field(
|
26
25
|
default=ResourceCategory.FRAMEWORK, frozen=True
|
27
26
|
)
|
@@ -72,7 +71,6 @@ class SynthlangFramework(Resource):
|
|
72
71
|
framework_options: list[FRAMEWORK_CHOICES] = None,
|
73
72
|
additional_text: str = "",
|
74
73
|
) -> str:
|
75
|
-
|
76
74
|
framework_options_text = self.build_framework_text(framework_options)
|
77
75
|
base_prompt = self.load_base_system_prompt()
|
78
76
|
template_details = (
|
@@ -297,8 +297,7 @@ def string_similarity(
|
|
297
297
|
score_func = algorithm
|
298
298
|
else:
|
299
299
|
raise ValueError(
|
300
|
-
"algorithm must be a string specifying a built-in algorithm or "
|
301
|
-
"a callable"
|
300
|
+
"algorithm must be a string specifying a built-in algorithm or a callable"
|
302
301
|
)
|
303
302
|
|
304
303
|
# Calculate similarities
|
lionagi/models/hashable_model.py
CHANGED
lionagi/models/schema_model.py
CHANGED
lionagi/operations/_act/act.py
CHANGED
@@ -23,10 +23,7 @@ async def interpret(
|
|
23
23
|
"Return only the re-written prompt. Do not assume any details not mentioned in the input, nor "
|
24
24
|
"give additional instruction than what is explicitly stated."
|
25
25
|
)
|
26
|
-
guidance =
|
27
|
-
f"Domain hint: {domain or 'general'}. "
|
28
|
-
f"Desired style: {style or 'concise'}. "
|
29
|
-
)
|
26
|
+
guidance = f"Domain hint: {domain or 'general'}. Desired style: {style or 'concise'}. "
|
30
27
|
if sample_writing:
|
31
28
|
guidance += f" Sample writing: {sample_writing}"
|
32
29
|
|
lionagi/operations/manager.py
CHANGED
lionagi/operations/plan/plan.py
CHANGED
@@ -65,7 +65,6 @@ def parse_to_representation(
|
|
65
65
|
|
66
66
|
|
67
67
|
def get_choice_representation(choice: Any) -> str:
|
68
|
-
|
69
68
|
if isinstance(choice, str):
|
70
69
|
return choice
|
71
70
|
|
@@ -77,7 +76,6 @@ def get_choice_representation(choice: Any) -> str:
|
|
77
76
|
|
78
77
|
|
79
78
|
def parse_selection(selection_str: str, choices: Any):
|
80
|
-
|
81
79
|
select_from = []
|
82
80
|
|
83
81
|
if isinstance(choices, dict):
|
lionagi/protocols/forms/flow.py
CHANGED
@@ -46,7 +46,9 @@ class FlowDefinition(BaseModel):
|
|
46
46
|
ins_str, outs_str = seg.split("->", 1)
|
47
47
|
inputs = [x.strip() for x in ins_str.split(",") if x.strip()]
|
48
48
|
outputs = [y.strip() for y in outs_str.split(",") if y.strip()]
|
49
|
-
step = FlowStep(
|
49
|
+
step = FlowStep(
|
50
|
+
name=f"step_{i + 1}", inputs=inputs, outputs=outputs
|
51
|
+
)
|
50
52
|
self.steps.append(step)
|
51
53
|
|
52
54
|
def get_required_fields(self) -> set[str]:
|
@@ -851,8 +851,7 @@ class Pile(Element, Collective[E], Generic[E]):
|
|
851
851
|
if self.strict_type:
|
852
852
|
if type(i) not in self.item_type:
|
853
853
|
raise TypeError(
|
854
|
-
"Invalid item type in pile."
|
855
|
-
f" Expected {self.item_type}",
|
854
|
+
f"Invalid item type in pile. Expected {self.item_type}",
|
856
855
|
)
|
857
856
|
else:
|
858
857
|
if not any(issubclass(type(i), t) for t in self.item_type):
|
lionagi/protocols/graph/graph.py
CHANGED
@@ -21,7 +21,6 @@ __all__ = ("Graph",)
|
|
21
21
|
|
22
22
|
|
23
23
|
class Graph(Element, Relational):
|
24
|
-
|
25
24
|
internal_nodes: Pile[Node] = Field(
|
26
25
|
default_factory=lambda: Pile(item_type={Node}, strict_type=False),
|
27
26
|
title="Internal Nodes",
|
@@ -52,8 +51,7 @@ class Graph(Element, Relational):
|
|
52
51
|
"""Add a node to the graph."""
|
53
52
|
if not isinstance(node, Relational):
|
54
53
|
raise RelationError(
|
55
|
-
"Failed to add node: Invalid node type: "
|
56
|
-
"not a <Relational> entity."
|
54
|
+
"Failed to add node: Invalid node type: not a <Relational> entity."
|
57
55
|
)
|
58
56
|
_id = ID.get_id(node)
|
59
57
|
try:
|
@@ -15,7 +15,6 @@ from .message import MessageRole, RoledMessage, Template, jinja_env
|
|
15
15
|
def prepare_assistant_response(
|
16
16
|
assistant_response: BaseModel | list[BaseModel] | dict | str | Any, /
|
17
17
|
) -> dict:
|
18
|
-
|
19
18
|
assistant_response = (
|
20
19
|
[assistant_response]
|
21
20
|
if not isinstance(assistant_response, list)
|
@@ -26,7 +25,6 @@ def prepare_assistant_response(
|
|
26
25
|
model_responses = []
|
27
26
|
|
28
27
|
for i in assistant_response:
|
29
|
-
|
30
28
|
if isinstance(i, BaseModel):
|
31
29
|
i = i.model_dump(exclude_none=True, exclude_unset=True)
|
32
30
|
|
@@ -73,6 +73,12 @@ class EndpointConfig(BaseModel):
|
|
73
73
|
|
74
74
|
return self
|
75
75
|
|
76
|
+
@field_validator("provider", mode="before")
|
77
|
+
def _validate_provider(cls, v: str):
|
78
|
+
if not v:
|
79
|
+
raise ValueError("Provider must be specified")
|
80
|
+
return v.strip().lower()
|
81
|
+
|
76
82
|
@property
|
77
83
|
def full_url(self):
|
78
84
|
if not self.endpoint_params:
|