lionagi 0.18.0__py3-none-any.whl → 0.18.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.
Files changed (93) hide show
  1. lionagi/__init__.py +102 -59
  2. lionagi/_errors.py +0 -5
  3. lionagi/adapters/spec_adapters/__init__.py +9 -0
  4. lionagi/adapters/spec_adapters/_protocol.py +236 -0
  5. lionagi/adapters/spec_adapters/pydantic_field.py +158 -0
  6. lionagi/fields.py +83 -0
  7. lionagi/ln/__init__.py +3 -1
  8. lionagi/ln/_async_call.py +2 -2
  9. lionagi/ln/concurrency/primitives.py +4 -4
  10. lionagi/ln/concurrency/task.py +1 -0
  11. lionagi/ln/fuzzy/_fuzzy_match.py +2 -2
  12. lionagi/ln/types/__init__.py +51 -0
  13. lionagi/ln/types/_sentinel.py +154 -0
  14. lionagi/ln/{types.py → types/base.py} +108 -168
  15. lionagi/ln/types/operable.py +221 -0
  16. lionagi/ln/types/spec.py +441 -0
  17. lionagi/models/field_model.py +69 -7
  18. lionagi/models/hashable_model.py +2 -3
  19. lionagi/models/model_params.py +4 -3
  20. lionagi/operations/ReAct/ReAct.py +1 -1
  21. lionagi/operations/act/act.py +3 -3
  22. lionagi/operations/builder.py +5 -7
  23. lionagi/operations/fields.py +380 -0
  24. lionagi/operations/flow.py +4 -6
  25. lionagi/operations/node.py +4 -4
  26. lionagi/operations/operate/operate.py +123 -89
  27. lionagi/operations/operate/operative.py +198 -0
  28. lionagi/operations/operate/step.py +203 -0
  29. lionagi/operations/select/select.py +1 -1
  30. lionagi/operations/select/utils.py +7 -1
  31. lionagi/operations/types.py +7 -7
  32. lionagi/protocols/action/manager.py +5 -6
  33. lionagi/protocols/contracts.py +2 -2
  34. lionagi/protocols/generic/__init__.py +22 -0
  35. lionagi/protocols/generic/element.py +36 -127
  36. lionagi/protocols/generic/pile.py +9 -10
  37. lionagi/protocols/generic/progression.py +23 -22
  38. lionagi/protocols/graph/edge.py +6 -5
  39. lionagi/protocols/ids.py +6 -49
  40. lionagi/protocols/messages/__init__.py +3 -1
  41. lionagi/protocols/messages/base.py +7 -6
  42. lionagi/protocols/messages/instruction.py +0 -1
  43. lionagi/protocols/messages/message.py +2 -2
  44. lionagi/protocols/types.py +1 -11
  45. lionagi/service/connections/__init__.py +3 -0
  46. lionagi/service/connections/providers/claude_code_cli.py +3 -2
  47. lionagi/service/hooks/_types.py +1 -1
  48. lionagi/service/hooks/_utils.py +1 -1
  49. lionagi/service/hooks/hook_event.py +3 -8
  50. lionagi/service/hooks/hook_registry.py +5 -5
  51. lionagi/service/hooks/hooked_event.py +61 -1
  52. lionagi/service/imodel.py +24 -20
  53. lionagi/service/third_party/claude_code.py +1 -2
  54. lionagi/service/third_party/openai_models.py +24 -22
  55. lionagi/service/token_calculator.py +1 -94
  56. lionagi/session/branch.py +26 -228
  57. lionagi/session/session.py +5 -90
  58. lionagi/version.py +1 -1
  59. {lionagi-0.18.0.dist-info → lionagi-0.18.2.dist-info}/METADATA +6 -5
  60. {lionagi-0.18.0.dist-info → lionagi-0.18.2.dist-info}/RECORD +62 -82
  61. lionagi/fields/__init__.py +0 -47
  62. lionagi/fields/action.py +0 -188
  63. lionagi/fields/base.py +0 -153
  64. lionagi/fields/code.py +0 -239
  65. lionagi/fields/file.py +0 -234
  66. lionagi/fields/instruct.py +0 -135
  67. lionagi/fields/reason.py +0 -55
  68. lionagi/fields/research.py +0 -52
  69. lionagi/operations/brainstorm/__init__.py +0 -2
  70. lionagi/operations/brainstorm/brainstorm.py +0 -498
  71. lionagi/operations/brainstorm/prompt.py +0 -11
  72. lionagi/operations/instruct/__init__.py +0 -2
  73. lionagi/operations/instruct/instruct.py +0 -28
  74. lionagi/operations/plan/__init__.py +0 -6
  75. lionagi/operations/plan/plan.py +0 -386
  76. lionagi/operations/plan/prompt.py +0 -25
  77. lionagi/operations/utils.py +0 -45
  78. lionagi/protocols/forms/__init__.py +0 -2
  79. lionagi/protocols/forms/base.py +0 -85
  80. lionagi/protocols/forms/flow.py +0 -79
  81. lionagi/protocols/forms/form.py +0 -86
  82. lionagi/protocols/forms/report.py +0 -48
  83. lionagi/protocols/mail/__init__.py +0 -2
  84. lionagi/protocols/mail/exchange.py +0 -220
  85. lionagi/protocols/mail/mail.py +0 -51
  86. lionagi/protocols/mail/mailbox.py +0 -103
  87. lionagi/protocols/mail/manager.py +0 -218
  88. lionagi/protocols/mail/package.py +0 -101
  89. lionagi/protocols/operatives/__init__.py +0 -2
  90. lionagi/protocols/operatives/operative.py +0 -362
  91. lionagi/protocols/operatives/step.py +0 -227
  92. {lionagi-0.18.0.dist-info → lionagi-0.18.2.dist-info}/WHEEL +0 -0
  93. {lionagi-0.18.0.dist-info → lionagi-0.18.2.dist-info}/licenses/LICENSE +0 -0
lionagi/session/branch.py CHANGED
@@ -2,52 +2,48 @@
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  from collections.abc import AsyncGenerator, Callable
5
- from typing import TYPE_CHECKING, Any, Literal, Optional
5
+ from typing import TYPE_CHECKING, Any, Literal
6
6
 
7
7
  from pydantic import BaseModel, Field, JsonValue, PrivateAttr, field_serializer
8
8
 
9
9
  from lionagi.config import settings
10
- from lionagi.fields import Instruct
10
+ from lionagi.ln import AlcallParams
11
11
  from lionagi.ln.types import Unset
12
12
  from lionagi.models.field_model import FieldModel
13
- from lionagi.operations.flow import AlcallParams
13
+ from lionagi.operations.fields import Instruct
14
14
  from lionagi.operations.manager import OperationManager
15
+ from lionagi.protocols._concepts import Relational
15
16
  from lionagi.protocols.action.manager import ActionManager
16
17
  from lionagi.protocols.action.tool import FuncTool, Tool, ToolRef
17
- from lionagi.protocols.types import (
18
+ from lionagi.protocols.generic import (
18
19
  ID,
19
- MESSAGE_FIELDS,
20
+ DataLogger,
21
+ DataLoggerConfig,
22
+ Element,
23
+ Log,
24
+ Pile,
25
+ Progression,
26
+ )
27
+ from lionagi.protocols.messages import (
20
28
  ActionRequest,
21
29
  ActionResponse,
22
30
  AssistantResponse,
23
- Communicatable,
24
- Element,
25
- IDType,
26
31
  Instruction,
27
- Log,
28
- LogManager,
29
- LogManagerConfig,
30
- Mail,
31
- Mailbox,
32
32
  MessageManager,
33
33
  MessageRole,
34
- PackageCategory,
35
- Pile,
36
- Progression,
37
- Relational,
38
34
  RoledMessage,
39
35
  SenderRecipient,
40
36
  System,
41
37
  )
42
- from lionagi.service import Endpoint, iModel, iModelManager
38
+ from lionagi.service.connections.endpoint import Endpoint
39
+ from lionagi.service.manager import iModel, iModelManager
43
40
  from lionagi.tools.base import LionTool
44
41
  from lionagi.utils import copy
45
42
 
46
43
  from .prompts import LION_SYSTEM_MESSAGE
47
44
 
48
45
  if TYPE_CHECKING:
49
- from lionagi.fields import Instruct
50
- from lionagi.protocols.operatives.operative import Operative
46
+ from lionagi.operations.operate.operative import Operative
51
47
 
52
48
 
53
49
  __all__ = ("Branch",)
@@ -56,7 +52,7 @@ __all__ = ("Branch",)
56
52
  _DEFAULT_ALCALL_PARAMS = None
57
53
 
58
54
 
59
- class Branch(Element, Communicatable, Relational):
55
+ class Branch(Element, Relational):
60
56
  """
61
57
  Manages a conversation 'branch' with messages, tools, and iModels.
62
58
 
@@ -65,20 +61,17 @@ class Branch(Element, Communicatable, Relational):
65
61
  - Registers and invokes tools/actions (`ActionManager`).
66
62
  - Manages model instances (`iModelManager`).
67
63
  - Logs activity (`LogManager`).
68
- - Communicates via mailboxes (`Mailbox`).
69
64
 
70
65
  **Key responsibilities**:
71
66
  - Storing and organizing messages, including system instructions, user instructions, and model responses.
72
67
  - Handling asynchronous or synchronous execution of LLM calls and tool invocations.
73
- - Providing a consistent interface for operate,” chat,” communicate,” parse,” etc.
68
+ - Providing a consistent interface for "operate," "chat," "communicate," "parse," etc.
74
69
 
75
70
  Attributes:
76
71
  user (SenderRecipient | None):
77
72
  The user or "owner" of this branch (often tied to a session).
78
73
  name (str | None):
79
74
  A human-readable name for this branch.
80
- mailbox (Mailbox):
81
- A mailbox for sending and receiving `Package` objects to/from other branches.
82
75
 
83
76
  Note:
84
77
  Actual implementations for chat, parse, operate, etc., are referenced
@@ -101,16 +94,10 @@ class Branch(Element, Communicatable, Relational):
101
94
  description="A human-readable name of the branch (optional).",
102
95
  )
103
96
 
104
- mailbox: Mailbox = Field(
105
- default_factory=Mailbox,
106
- exclude=True,
107
- description="Mailbox for cross-branch or external communication.",
108
- )
109
-
110
97
  _message_manager: MessageManager | None = PrivateAttr(None)
111
98
  _action_manager: ActionManager | None = PrivateAttr(None)
112
99
  _imodel_manager: iModelManager | None = PrivateAttr(None)
113
- _log_manager: LogManager | None = PrivateAttr(None)
100
+ _log_manager: DataLogger | None = PrivateAttr(None)
114
101
  _operation_manager: OperationManager | None = PrivateAttr(None)
115
102
 
116
103
  def __init__(
@@ -125,7 +112,7 @@ class Branch(Element, Communicatable, Relational):
125
112
  parse_model: iModel | dict = None,
126
113
  imodel: iModel = None, # deprecated, alias of chat_model
127
114
  tools: FuncTool | list[FuncTool] = None, # ActionManager kwargs
128
- log_config: LogManagerConfig | dict = None, # LogManager kwargs
115
+ log_config: DataLoggerConfig | dict = None, # LogManager kwargs
129
116
  system_datetime: bool | str = None,
130
117
  system_template=None,
131
118
  system_template_context: dict = None,
@@ -229,10 +216,10 @@ class Branch(Element, Communicatable, Relational):
229
216
  # --- LogManager ---
230
217
  if log_config:
231
218
  if isinstance(log_config, dict):
232
- log_config = LogManagerConfig(**log_config)
233
- self._log_manager = LogManager.from_config(log_config, logs=logs)
219
+ log_config = DataLoggerConfig(**log_config)
220
+ self._log_manager = DataLogger.from_config(log_config, logs=logs)
234
221
  else:
235
- self._log_manager = LogManager(**settings.LOG_CONFIG, logs=logs)
222
+ self._log_manager = DataLogger(**settings.LOG_CONFIG, logs=logs)
236
223
 
237
224
  self._operation_manager = OperationManager()
238
225
 
@@ -414,6 +401,7 @@ class Branch(Element, Communicatable, Relational):
414
401
  pd.DataFrame: Each row represents a message, with columns defined by MESSAGE_FIELDS.
415
402
  """
416
403
  from lionagi.protocols.generic.pile import Pile
404
+ from lionagi.protocols.messages.base import MESSAGE_FIELDS
417
405
 
418
406
  if progression is None:
419
407
  progression = self.msgs.progression
@@ -426,170 +414,6 @@ class Branch(Element, Communicatable, Relational):
426
414
  p = Pile(collections=msgs)
427
415
  return p.to_df(columns=MESSAGE_FIELDS)
428
416
 
429
- # -------------------------------------------------------------------------
430
- # Mailbox Send / Receive
431
- # -------------------------------------------------------------------------
432
- def send(
433
- self,
434
- recipient: IDType,
435
- category: Optional["PackageCategory"],
436
- item: Any,
437
- request_source: IDType | None = None,
438
- ) -> None:
439
- """
440
- Sends a `Package` (wrapped in a `Mail` object) to a specified recipient.
441
-
442
- Args:
443
- recipient (IDType):
444
- ID of the recipient branch or component.
445
- category (PackageCategory | None):
446
- The category/type of the package (e.g., 'message', 'tool', 'imodel').
447
- item (Any):
448
- The payload to send (e.g., a message, tool reference, model, etc.).
449
- request_source (IDType | None):
450
- The ID that prompted or requested this send operation (optional).
451
- """
452
- from lionagi.protocols.mail.package import Package
453
-
454
- package = Package(
455
- category=category,
456
- item=item,
457
- request_source=request_source,
458
- )
459
-
460
- mail = Mail(
461
- sender=self.id,
462
- recipient=recipient,
463
- package=package,
464
- )
465
- self.mailbox.append_out(mail)
466
-
467
- def receive(
468
- self,
469
- sender: IDType,
470
- message: bool = False,
471
- tool: bool = False,
472
- imodel: bool = False,
473
- ) -> None:
474
- """
475
- Retrieves and processes mail from a given sender according to the specified flags.
476
-
477
- Args:
478
- sender (IDType):
479
- The ID of the mail sender.
480
- message (bool):
481
- If `True`, process packages categorized as "message".
482
- tool (bool):
483
- If `True`, process packages categorized as "tool".
484
- imodel (bool):
485
- If `True`, process packages categorized as "imodel".
486
-
487
- Raises:
488
- ValueError: If no mail exists from the specified sender,
489
- or if a package is invalid for the chosen category.
490
- """
491
- sender = ID.get_id(sender)
492
- if sender not in self.mailbox.pending_ins.keys():
493
- raise ValueError(f"No mail or package found from sender: {sender}")
494
-
495
- skipped_requests = Progression()
496
- while self.mailbox.pending_ins[sender]:
497
- mail_id = self.mailbox.pending_ins[sender].popleft()
498
- mail: Mail = self.mailbox.pile_[mail_id]
499
-
500
- if mail.category == "message" and message:
501
- if not isinstance(mail.package.item, RoledMessage):
502
- raise ValueError(
503
- "Invalid message package: The item must be a `RoledMessage`."
504
- )
505
- new_message = mail.package.item.model_copy(deep=True)
506
- new_message.sender = mail.sender
507
- new_message.recipient = self.id
508
- self.msgs.messages.include(new_message)
509
- self.mailbox.pile_.pop(mail_id)
510
-
511
- elif mail.category == "tool" and tool:
512
- if not isinstance(mail.package.item, Tool):
513
- raise ValueError(
514
- "Invalid tool package: The item must be a `Tool` instance."
515
- )
516
- self._action_manager.register_tools(mail.package.item)
517
- self.mailbox.pile_.pop(mail_id)
518
-
519
- elif mail.category == "imodel" and imodel:
520
- if not isinstance(mail.package.item, iModel):
521
- raise ValueError(
522
- "Invalid iModel package: The item must be an `iModel` instance."
523
- )
524
- self._imodel_manager.register_imodel(
525
- mail.package.item.name or "chat", mail.package.item
526
- )
527
- self.mailbox.pile_.pop(mail_id)
528
-
529
- else:
530
- # If the category doesn't match the flags or is unhandled
531
- skipped_requests.append(mail)
532
-
533
- # Requeue any skipped mail
534
- self.mailbox.pending_ins[sender] = skipped_requests
535
- if len(self.mailbox.pending_ins[sender]) == 0:
536
- self.mailbox.pending_ins.pop(sender)
537
-
538
- async def asend(
539
- self,
540
- recipient: IDType,
541
- category: PackageCategory | None,
542
- package: Any,
543
- request_source: IDType | None = None,
544
- ):
545
- """
546
- Async version of `send()`.
547
-
548
- Args:
549
- recipient (IDType):
550
- ID of the recipient branch or component.
551
- category (PackageCategory | None):
552
- The category/type of the package.
553
- package (Any):
554
- The item(s) to send (message/tool/model).
555
- request_source (IDType | None):
556
- The origin request ID (if any).
557
- """
558
- async with self.mailbox.pile_:
559
- self.send(recipient, category, package, request_source)
560
-
561
- async def areceive(
562
- self,
563
- sender: IDType,
564
- message: bool = False,
565
- tool: bool = False,
566
- imodel: bool = False,
567
- ) -> None:
568
- """
569
- Async version of `receive()`.
570
-
571
- Args:
572
- sender (IDType):
573
- The ID of the mail sender.
574
- message (bool):
575
- If `True`, process packages categorized as "message".
576
- tool (bool):
577
- If `True`, process packages categorized as "tool".
578
- imodel (bool):
579
- If `True`, process packages categorized as "imodel".
580
- """
581
- async with self.mailbox.pile_:
582
- self.receive(sender, message, tool, imodel)
583
-
584
- def receive_all(self) -> None:
585
- """
586
- Receives mail from all known senders without filtering.
587
-
588
- (Duplicate method included in your snippet; you may unify or remove.)
589
- """
590
- for key in self.mailbox.pending_ins:
591
- self.receive(key)
592
-
593
417
  def connect(
594
418
  self,
595
419
  provider: str = None,
@@ -892,13 +716,14 @@ class Branch(Element, Communicatable, Relational):
892
716
  BaseModel | dict | str | None:
893
717
  Parsed model instance, or a fallback based on `handle_validation`.
894
718
  """
895
- from lionagi.operations.parse.parse import parse, prepare_parse_kws
896
719
 
897
720
  _pms = {
898
721
  k: v
899
722
  for k, v in locals().items()
900
723
  if k not in ("self", "_pms") and v is not None
901
724
  }
725
+ from lionagi.operations.parse.parse import parse, prepare_parse_kws
726
+
902
727
  return await parse(self, **prepare_parse_kws(self, **_pms))
903
728
 
904
729
  async def operate(
@@ -1197,33 +1022,6 @@ class Branch(Element, Communicatable, Relational):
1197
1022
 
1198
1023
  return await interpret(self, **prepare_interpret_kw(self, **_pms))
1199
1024
 
1200
- async def instruct(
1201
- self,
1202
- instruct: "Instruct",
1203
- /,
1204
- **kwargs,
1205
- ):
1206
- """
1207
- A convenience method that chooses between `operate()` and `communicate()`
1208
- based on the contents of an `Instruct` object.
1209
-
1210
- If the `Instruct` indicates tool usage or advanced response format,
1211
- `operate()` is used. Otherwise, it defaults to `communicate()`.
1212
-
1213
- Args:
1214
- instruct (Instruct):
1215
- An object containing `instruction`, `guidance`, `context`, etc.
1216
- **kwargs:
1217
- Additional args forwarded to `operate()` or `communicate()`.
1218
-
1219
- Returns:
1220
- Any:
1221
- The result of the underlying call (structured object, raw text, etc.).
1222
- """
1223
- from lionagi.operations.instruct.instruct import instruct as _ins
1224
-
1225
- return await _ins(self, instruct, **kwargs)
1226
-
1227
1025
  async def ReAct(
1228
1026
  self,
1229
1027
  instruct: "Instruct | dict[str, Any]",
@@ -4,6 +4,7 @@
4
4
  import contextlib
5
5
  from collections.abc import Callable
6
6
  from typing import Any
7
+ from uuid import UUID
7
8
 
8
9
  from pydantic import (
9
10
  Field,
@@ -17,11 +18,7 @@ from typing_extensions import Self
17
18
  from lionagi.protocols.types import (
18
19
  ID,
19
20
  MESSAGE_FIELDS,
20
- Communicatable,
21
- Exchange,
22
21
  Graph,
23
- IDType,
24
- MailManager,
25
22
  Node,
26
23
  Pile,
27
24
  Progression,
@@ -37,25 +34,19 @@ from ..service.imodel import iModel
37
34
  from .branch import ActionManager, Branch, OperationManager, Tool
38
35
 
39
36
 
40
- class Session(Node, Communicatable, Relational):
37
+ class Session(Node, Relational):
41
38
  """
42
- Manages multiple conversation branches and mail transfer in a session.
39
+ Manages multiple conversation branches in a session.
43
40
 
44
41
  Attributes:
45
42
  branches (Pile | None): Collection of conversation branches.
46
43
  default_branch (Branch | None): The default conversation branch.
47
- mail_transfer (Exchange | None): Mail transfer system.
48
- mail_manager (MailManager | None): Manages mail operations.
49
44
  """
50
45
 
51
46
  branches: Pile[Branch] = Field(
52
47
  default_factory=lambda: Pile(item_type={Branch}, strict_type=False)
53
48
  )
54
49
  default_branch: Any = Field(default=None, exclude=True)
55
- mail_transfer: Exchange = Field(default_factory=Exchange, exclude=True)
56
- mail_manager: MailManager = Field(
57
- default_factory=MailManager, exclude=True
58
- )
59
50
  name: str = Field(default="Session")
60
51
  user: SenderRecipient | None = None
61
52
  _operation_manager: OperationManager = PrivateAttr(
@@ -76,7 +67,6 @@ class Session(Node, Communicatable, Relational):
76
67
  def _take_in_branch(branch: Branch):
77
68
  if branch not in self.branches:
78
69
  self.branches.include(branch)
79
- self.mail_manager.add_sources(branch)
80
70
 
81
71
  branch.user = self.id
82
72
  branch._operation_manager = self._operation_manager
@@ -119,7 +109,7 @@ class Session(Node, Communicatable, Relational):
119
109
  return decorator
120
110
 
121
111
  @model_validator(mode="after")
122
- def _add_mail_sources(self) -> Self:
112
+ def _initialize_branches(self) -> Self:
123
113
  if self.default_branch is None:
124
114
  self.default_branch = Branch()
125
115
  if self.default_branch not in self.branches:
@@ -196,7 +186,6 @@ class Session(Node, Communicatable, Relational):
196
186
  branch: Branch = self.branches[branch]
197
187
 
198
188
  self.branches.exclude(branch)
199
- self.mail_manager.delete_source(branch.id)
200
189
 
201
190
  if self.default_branch.id == branch.id:
202
191
  if not self.branches:
@@ -288,80 +277,6 @@ class Session(Node, Communicatable, Relational):
288
277
  collections=messages, item_type={RoledMessage}, strict_type=False
289
278
  )
290
279
 
291
- def send(self, to_: ID.RefSeq = None):
292
- """
293
- Send mail to specified branches.
294
-
295
- Args:
296
- to_: The branches to send mail to. If None, send to all.
297
-
298
- Raises:
299
- ValueError: If mail sending fails.
300
- """
301
- if to_ is None:
302
- self.mail_manager.send_all()
303
- else:
304
- try:
305
- lcall(
306
- to_,
307
- lambda x: self.mail_manager.send(ID.get_id(x)),
308
- input_unique=True,
309
- input_flatten=True,
310
- input_dropna=True,
311
- input_use_values=True,
312
- )
313
- except Exception as e:
314
- raise ValueError(f"Failed to send mail. Error: {e}")
315
-
316
- async def acollect_send_all(self, receive_all: bool = True):
317
- """
318
- Collect and send mail for all branches, optionally receiving all mail.
319
-
320
- Args:
321
- receive_all: If True, receive all mail for all branches.
322
- """
323
- async with self.mail_manager.sources:
324
- self.collect_send_all(receive_all)
325
-
326
- def collect_send_all(self, receive_all: bool = True):
327
- """
328
- Collect and send mail for all branches, optionally receiving all mail.
329
-
330
- Args:
331
- receive_all: If True, receive all mail for all branches.
332
- """
333
- self.collect()
334
- self.send()
335
- if receive_all:
336
- for i in self.branches:
337
- i.receive_all()
338
-
339
- def collect(self, from_: ID.RefSeq = None):
340
- """
341
- Collect mail from specified branches.
342
-
343
- Args:
344
- from_: The branches to collect mail from. If None, collect
345
- from all.
346
-
347
- Raises:
348
- ValueError: If mail collection fails.
349
- """
350
- if from_ is None:
351
- self.mail_manager.collect_all()
352
- else:
353
- try:
354
- lcall(
355
- from_,
356
- lambda x: self.mail_manager.collect(ID.get_id(x)),
357
- input_flatten=True,
358
- input_dropna=True,
359
- input_unique=True,
360
- input_use_values=True,
361
- )
362
- except Exception as e:
363
- raise ValueError(f"Failed to collect mail. Error: {e}")
364
-
365
280
  async def flow(
366
281
  self,
367
282
  graph: Graph,
@@ -395,7 +310,7 @@ class Session(Node, Communicatable, Relational):
395
310
 
396
311
  # Use specified branch or session's default
397
312
  branch = default_branch or self.default_branch
398
- if isinstance(branch, (str, IDType)):
313
+ if isinstance(branch, (str, UUID)):
399
314
  branch = self.branches[branch]
400
315
 
401
316
  return await flow(
lionagi/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.18.0"
1
+ __version__ = "0.18.2"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lionagi
3
- Version: 0.18.0
3
+ Version: 0.18.2
4
4
  Summary: An Intelligence Operating System.
5
5
  Author-email: HaiyangLi <quantocean.li@gmail.com>
6
6
  License: Apache License
@@ -227,7 +227,7 @@ Requires-Dist: json-repair>=0.40.0
227
227
  Requires-Dist: msgspec>=0.18.0
228
228
  Requires-Dist: pydantic-settings>=2.8.0
229
229
  Requires-Dist: pydantic>=2.8.0
230
- Requires-Dist: pydapter[pandas]>=1.1.1
230
+ Requires-Dist: pydapter[pandas]>=1.2.0
231
231
  Requires-Dist: python-dotenv>=1.1.0
232
232
  Requires-Dist: tiktoken>=0.9.0
233
233
  Provides-Extra: all
@@ -240,6 +240,7 @@ Requires-Dist: networkx>=3.0.0; extra == 'all'
240
240
  Requires-Dist: ollama>=0.4.0; extra == 'all'
241
241
  Requires-Dist: pydapter[postgres]; extra == 'all'
242
242
  Requires-Dist: rich>=13.0.0; extra == 'all'
243
+ Requires-Dist: xmltodict>=0.12.0; extra == 'all'
243
244
  Provides-Extra: graph
244
245
  Requires-Dist: matplotlib>=3.7.0; extra == 'graph'
245
246
  Requires-Dist: networkx>=3.0.0; extra == 'graph'
@@ -465,13 +466,13 @@ from lionagi.fields import LIST_INSTRUCT_FIELD_MODEL, Instruct
465
466
  response3 = await orchestrator.operate(
466
467
  instruct=Instruct(
467
468
  instruction="create 4 research questions for parallel discovery",
468
- guidance="put into `instruct_models` field as part of your structured result message",
469
+ guidance="put into `instruct_model` field as part of your structured result message",
469
470
  context="I'd like to create an orchestration system for AI agents using lionagi"
470
471
  ),
471
472
  field_models=[LIST_INSTRUCT_FIELD_MODEL],
472
473
  )
473
474
 
474
- len(response3.instruct_models) # should be 4
475
+ len(response3.instruct_model) # should be 4
475
476
 
476
477
  async def handle_instruct(instruct):
477
478
  sub_branch = Branch(
@@ -482,7 +483,7 @@ async def handle_instruct(instruct):
482
483
 
483
484
  # run in parallel across all instruct models
484
485
  from lionagi.ln import alcall
485
- responses = await alcall(response3.instruct_models, handle_instruct)
486
+ responses = await alcall(response3.instruct_model, handle_instruct)
486
487
 
487
488
  # now hand these reports back to the orchestrator
488
489
  final_response = await orchestrator.communicate(