lionagi 0.18.0__py3-none-any.whl → 0.18.1__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 (78) hide show
  1. lionagi/_errors.py +0 -5
  2. lionagi/fields.py +83 -0
  3. lionagi/ln/__init__.py +3 -1
  4. lionagi/ln/concurrency/primitives.py +4 -4
  5. lionagi/ln/concurrency/task.py +1 -0
  6. lionagi/models/field_model.py +12 -4
  7. lionagi/models/hashable_model.py +2 -3
  8. lionagi/operations/ReAct/ReAct.py +1 -1
  9. lionagi/operations/act/act.py +3 -3
  10. lionagi/operations/builder.py +5 -7
  11. lionagi/operations/fields.py +380 -0
  12. lionagi/operations/flow.py +4 -6
  13. lionagi/operations/node.py +4 -4
  14. lionagi/operations/operate/operate.py +9 -7
  15. lionagi/{protocols/operatives → operations/operate}/operative.py +4 -5
  16. lionagi/{protocols/operatives → operations/operate}/step.py +34 -39
  17. lionagi/operations/select/select.py +1 -1
  18. lionagi/operations/select/utils.py +7 -1
  19. lionagi/operations/types.py +1 -1
  20. lionagi/protocols/action/manager.py +5 -6
  21. lionagi/protocols/contracts.py +2 -2
  22. lionagi/protocols/generic/__init__.py +22 -0
  23. lionagi/protocols/generic/element.py +36 -127
  24. lionagi/protocols/generic/pile.py +9 -10
  25. lionagi/protocols/generic/progression.py +23 -22
  26. lionagi/protocols/graph/edge.py +6 -5
  27. lionagi/protocols/ids.py +6 -49
  28. lionagi/protocols/messages/__init__.py +3 -1
  29. lionagi/protocols/messages/base.py +7 -6
  30. lionagi/protocols/messages/instruction.py +0 -1
  31. lionagi/protocols/types.py +1 -11
  32. lionagi/service/connections/__init__.py +3 -0
  33. lionagi/service/connections/providers/claude_code_cli.py +3 -2
  34. lionagi/service/hooks/_types.py +1 -1
  35. lionagi/service/hooks/_utils.py +1 -1
  36. lionagi/service/hooks/hook_event.py +3 -8
  37. lionagi/service/hooks/hook_registry.py +5 -5
  38. lionagi/service/hooks/hooked_event.py +61 -1
  39. lionagi/service/imodel.py +24 -20
  40. lionagi/service/third_party/claude_code.py +1 -2
  41. lionagi/service/third_party/openai_models.py +24 -22
  42. lionagi/service/token_calculator.py +1 -94
  43. lionagi/session/branch.py +26 -228
  44. lionagi/session/session.py +5 -90
  45. lionagi/version.py +1 -1
  46. {lionagi-0.18.0.dist-info → lionagi-0.18.1.dist-info}/METADATA +6 -5
  47. {lionagi-0.18.0.dist-info → lionagi-0.18.1.dist-info}/RECORD +49 -76
  48. lionagi/fields/__init__.py +0 -47
  49. lionagi/fields/action.py +0 -188
  50. lionagi/fields/base.py +0 -153
  51. lionagi/fields/code.py +0 -239
  52. lionagi/fields/file.py +0 -234
  53. lionagi/fields/instruct.py +0 -135
  54. lionagi/fields/reason.py +0 -55
  55. lionagi/fields/research.py +0 -52
  56. lionagi/operations/brainstorm/__init__.py +0 -2
  57. lionagi/operations/brainstorm/brainstorm.py +0 -498
  58. lionagi/operations/brainstorm/prompt.py +0 -11
  59. lionagi/operations/instruct/__init__.py +0 -2
  60. lionagi/operations/instruct/instruct.py +0 -28
  61. lionagi/operations/plan/__init__.py +0 -6
  62. lionagi/operations/plan/plan.py +0 -386
  63. lionagi/operations/plan/prompt.py +0 -25
  64. lionagi/operations/utils.py +0 -45
  65. lionagi/protocols/forms/__init__.py +0 -2
  66. lionagi/protocols/forms/base.py +0 -85
  67. lionagi/protocols/forms/flow.py +0 -79
  68. lionagi/protocols/forms/form.py +0 -86
  69. lionagi/protocols/forms/report.py +0 -48
  70. lionagi/protocols/mail/__init__.py +0 -2
  71. lionagi/protocols/mail/exchange.py +0 -220
  72. lionagi/protocols/mail/mail.py +0 -51
  73. lionagi/protocols/mail/mailbox.py +0 -103
  74. lionagi/protocols/mail/manager.py +0 -218
  75. lionagi/protocols/mail/package.py +0 -101
  76. lionagi/protocols/operatives/__init__.py +0 -2
  77. {lionagi-0.18.0.dist-info → lionagi-0.18.1.dist-info}/WHEEL +0 -0
  78. {lionagi-0.18.0.dist-info → lionagi-0.18.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,218 +0,0 @@
1
- # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
2
- # SPDX-License-Identifier: Apache-2.0
3
-
4
- import asyncio
5
- from collections import deque
6
- from typing import Any
7
-
8
- from lionagi._errors import ItemNotFoundError
9
-
10
- from .._concepts import Manager, Observable
11
- from ..generic.element import ID, IDType
12
- from ..generic.pile import Pile, to_list_type
13
- from .exchange import Exchange
14
- from .mail import Mail, Package, PackageCategory
15
-
16
-
17
- class MailManager(Manager):
18
- """
19
- A manager for mail operations across various observable sources
20
- within LionAGI. Unlike `Exchange`, this class can manage the state
21
- of multiple sources in a more general or higher-level context,
22
- storing mail queues in a dictionary rather than individual buffers.
23
-
24
- Attributes
25
- ----------
26
- sources : Pile[Observable]
27
- A concurrency-safe collection of known sources.
28
- mails : dict[str, dict[str, deque]]
29
- A nested mapping of recipient -> sender -> queue of mail.
30
- execute_stop : bool
31
- Controls the asynchronous execution loop; set to True to exit.
32
- """
33
-
34
- def __init__(self, sources: ID.Item | ID.ItemSeq = None) -> None:
35
- """
36
- Initialize a MailManager instance.
37
-
38
- Parameters
39
- ----------
40
- sources : ID.Item | ID.ItemSeq, optional
41
- Initial source(s) to manage. Each source must be an Observable.
42
- """
43
- self.sources: Pile[Observable] = Pile()
44
- self.mails: dict[str, dict[str, deque]] = {}
45
- self.execute_stop: bool = False
46
-
47
- if sources:
48
- self.add_sources(sources)
49
-
50
- def add_sources(self, sources: ID.Item | ID.ItemSeq, /) -> None:
51
- """
52
- Register new sources in the MailManager.
53
-
54
- Parameters
55
- ----------
56
- sources : ID.Item | ID.ItemSeq
57
- A single source or multiple sources to be added.
58
-
59
- Raises
60
- ------
61
- ValueError
62
- If adding the sources fails for any reason.
63
- """
64
- try:
65
- sources = to_list_type(sources)
66
- self.sources.include(sources)
67
- for item in sources:
68
- self.mails[item.id] = {}
69
- except Exception as e:
70
- raise ValueError("Failed to add source.") from e
71
-
72
- @staticmethod
73
- def create_mail(
74
- sender: ID.Ref,
75
- recipient: ID.Ref,
76
- category: PackageCategory | str,
77
- package: Any,
78
- request_source: Any = None,
79
- ) -> Mail:
80
- """
81
- Factory method to generate a Mail object.
82
-
83
- Parameters
84
- ----------
85
- sender : ID.Ref
86
- Reference (ID or object) for the sender.
87
- recipient : ID.Ref
88
- Reference (ID or object) for the recipient.
89
- category : PackageCategory | str
90
- The category of this package.
91
- package : Any
92
- The payload or content in the mail.
93
- request_source : Any, optional
94
- Additional context about the request source.
95
-
96
- Returns
97
- -------
98
- Mail
99
- A new mail object with specified sender, recipient, and package.
100
- """
101
- pack = Package(
102
- category=category, package=package, request_source=request_source
103
- )
104
- return Mail(sender=sender, recipient=recipient, package=pack)
105
-
106
- def delete_source(self, source_id: IDType) -> None:
107
- """
108
- Remove a source from the manager, discarding any associated mail.
109
-
110
- Parameters
111
- ----------
112
- source_id : IDType
113
- The ID of the source to be removed.
114
-
115
- Raises
116
- ------
117
- ItemNotFoundError
118
- If the given source ID is not present.
119
- """
120
- if source_id not in self.sources:
121
- raise ItemNotFoundError(f"Source {source_id} does not exist.")
122
- self.sources.pop(source_id)
123
- self.mails.pop(source_id)
124
-
125
- def collect(self, sender: IDType) -> None:
126
- """
127
- Collect outbound mail from a single source.
128
-
129
- Parameters
130
- ----------
131
- sender : IDType
132
- The ID of the sender whose outbound mail is retrieved.
133
-
134
- Raises
135
- ------
136
- ItemNotFoundError
137
- If the sender is not recognized.
138
- """
139
- if sender not in self.sources:
140
- raise ItemNotFoundError(f"Sender source {sender} does not exist.")
141
- mailbox: Exchange = (
142
- self.sources[sender]
143
- if isinstance(self.sources[sender], Exchange)
144
- else self.sources[sender].mailbox
145
- )
146
- while mailbox.pending_outs.size() > 0:
147
- mail_id = mailbox.pending_outs.popleft()
148
- mail: Mail = mailbox.pile_.pop(mail_id)
149
- if mail.recipient not in self.sources:
150
- rec_ = mail.recipient
151
- raise ItemNotFoundError(
152
- f"Recipient source {rec_} does not exist"
153
- )
154
- if mail.sender not in self.mails[mail.recipient]:
155
- self.mails[mail.recipient].update({mail.sender: deque()})
156
- self.mails[mail.recipient][mail.sender].append(mail)
157
-
158
- def send(self, recipient: IDType) -> None:
159
- """
160
- Send any pending mail to a specified recipient.
161
-
162
- Parameters
163
- ----------
164
- recipient : IDType
165
- The ID of the recipient to which mail should be delivered.
166
-
167
- Raises
168
- ------
169
- ItemNotFoundError
170
- If the recipient ID is not recognized.
171
- """
172
- if recipient not in self.sources:
173
- raise ItemNotFoundError(
174
- f"Recipient source {recipient} does not exist."
175
- )
176
- if not self.mails[recipient]:
177
- return
178
- for key in list(self.mails[recipient].keys()):
179
- pending_mails = self.mails[recipient].pop(key)
180
- mailbox: Exchange = (
181
- self.sources[recipient]
182
- if isinstance(self.sources[recipient], Exchange)
183
- else self.sources[recipient].mailbox
184
- )
185
- while pending_mails:
186
- mail = pending_mails.popleft()
187
- mailbox.include(mail, direction="in")
188
-
189
- def collect_all(self) -> None:
190
- """
191
- Collect outbound mail from all known sources.
192
- """
193
- for source in self.sources:
194
- self.collect(sender=source.id)
195
-
196
- def send_all(self) -> None:
197
- """
198
- Send mail to all known recipients who have pending items.
199
- """
200
- for source in self.sources:
201
- self.send(recipient=source.id)
202
-
203
- async def execute(self, refresh_time: int = 1) -> None:
204
- """
205
- Continuously collect and send mail in an asynchronous loop.
206
-
207
- Parameters
208
- ----------
209
- refresh_time : int, optional
210
- Delay (in seconds) between each collect/send cycle.
211
- """
212
- while not self.execute_stop:
213
- self.collect_all()
214
- self.send_all()
215
- await asyncio.sleep(refresh_time)
216
-
217
-
218
- # File: lion_core/communication/manager.py
@@ -1,101 +0,0 @@
1
- # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
2
- # SPDX-License-Identifier: Apache-2.0
3
-
4
- from enum import Enum
5
- from typing import Any
6
-
7
- from lionagi.ln import now_utc
8
- from lionagi.protocols.generic.element import ID, IDType
9
-
10
- from .._concepts import Communicatable, Observable
11
-
12
-
13
- class PackageCategory(str, Enum):
14
- """
15
- Enumeration of common package categories in LionAGI:
16
-
17
- - MESSAGE: General message content
18
- - TOOL: A tool or action to be invoked
19
- - IMODEL: Some internal model reference
20
- - NODE: A node in a graph
21
- - NODE_LIST: A list of nodes
22
- - NODE_ID: A node ID
23
- - START: A 'start' signal
24
- - END: An 'end' signal
25
- - CONDITION: A condition or gating logic
26
- - SIGNAL: A more generic signal or marker
27
- """
28
-
29
- MESSAGE = "message"
30
- TOOL = "tool"
31
- IMODEL = "imodel"
32
- NODE = "node"
33
- NODE_LIST = "node_list"
34
- NODE_ID = "node_id"
35
- START = "start"
36
- END = "end"
37
- CONDITION = "condition"
38
- SIGNAL = "signal"
39
-
40
-
41
- def validate_category(value: Any) -> PackageCategory:
42
- """
43
- Validate and convert the input to a valid PackageCategory.
44
-
45
- Parameters
46
- ----------
47
- value : Any
48
- The input to interpret as a `PackageCategory`.
49
-
50
- Returns
51
- -------
52
- PackageCategory
53
- The validated category.
54
-
55
- Raises
56
- ------
57
- ValueError
58
- If the value cannot be converted into a valid package category.
59
- """
60
- if isinstance(value, PackageCategory):
61
- return value
62
- try:
63
- return PackageCategory(str(value))
64
- except ValueError as e:
65
- raise ValueError("Invalid value for category.") from e
66
-
67
-
68
- class Package(Observable):
69
- """
70
- A self-contained package that can be attached to `Mail` items.
71
- Includes a unique ID, creation timestamp, category, payload item,
72
- and an optional request source for context.
73
-
74
- Attributes
75
- ----------
76
- category : PackageCategory
77
- The classification or type of package.
78
- item : Any
79
- The main payload or data of this package.
80
- request_source : ID[Communicatable] | None
81
- An optional reference indicating the origin or context
82
- for this package.
83
- """
84
-
85
- __slots__ = ("id", "created_at", "category", "item", "request_source")
86
-
87
- def __init__(
88
- self,
89
- category: PackageCategory,
90
- item: Any,
91
- request_source: ID[Communicatable] = None,
92
- ):
93
- super().__init__()
94
- self.id = IDType.create()
95
- self.created_at = now_utc().timestamp()
96
- self.category = validate_category(category)
97
- self.item = item
98
- self.request_source = request_source
99
-
100
-
101
- # File: lionagi/protocols/mail/package.py
@@ -1,2 +0,0 @@
1
- # Copyright (c) 2023-2025, HaiyangLi <quantocean.li at gmail dot com>
2
- # SPDX-License-Identifier: Apache-2.0