lionagi 0.13.4__py3-none-any.whl → 0.13.6__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/__init__.py +8 -0
- lionagi/_types.py +6 -0
- lionagi/fields/__init__.py +20 -3
- lionagi/libs/schema/load_pydantic_model_from_schema.py +4 -6
- lionagi/operations/__init__.py +16 -1
- lionagi/operations/builder.py +664 -0
- lionagi/operations/flow.py +7 -21
- lionagi/operations/utils.py +3 -1
- lionagi/service/connections/endpoint_config.py +12 -1
- lionagi/version.py +1 -1
- {lionagi-0.13.4.dist-info → lionagi-0.13.6.dist-info}/METADATA +4 -3
- {lionagi-0.13.4.dist-info → lionagi-0.13.6.dist-info}/RECORD +14 -13
- {lionagi-0.13.4.dist-info → lionagi-0.13.6.dist-info}/WHEEL +0 -0
- {lionagi-0.13.4.dist-info → lionagi-0.13.6.dist-info}/licenses/LICENSE +0 -0
lionagi/__init__.py
CHANGED
@@ -7,6 +7,9 @@ import logging
|
|
7
7
|
from pydantic import BaseModel, Field
|
8
8
|
|
9
9
|
from . import _types as types
|
10
|
+
from .operations import Operation
|
11
|
+
from .operations import OperationGraphBuilder as Builder
|
12
|
+
from .operations import brainstorm, flow, plan
|
10
13
|
from .service.imodel import iModel
|
11
14
|
from .session.session import Branch, Session
|
12
15
|
from .version import __version__
|
@@ -23,4 +26,9 @@ __all__ = (
|
|
23
26
|
"BaseModel",
|
24
27
|
"Field",
|
25
28
|
"logger",
|
29
|
+
"Builder",
|
30
|
+
"Operation",
|
31
|
+
"brainstorm",
|
32
|
+
"flow",
|
33
|
+
"plan",
|
26
34
|
)
|
lionagi/_types.py
CHANGED
lionagi/fields/__init__.py
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
-
from .action import
|
1
|
+
from .action import (
|
2
|
+
ACTION_REQUESTS_FIELD,
|
3
|
+
ACTION_REQUIRED_FIELD,
|
4
|
+
ACTION_RESPONSES_FIELD,
|
5
|
+
ActionRequestModel,
|
6
|
+
ActionResponseModel,
|
7
|
+
)
|
2
8
|
from .base import (
|
3
9
|
CodeSnippet,
|
4
10
|
Outline,
|
@@ -8,8 +14,13 @@ from .base import (
|
|
8
14
|
TextSnippet,
|
9
15
|
)
|
10
16
|
from .file import Documentation, File, Module, ResearchSummary
|
11
|
-
from .instruct import
|
12
|
-
|
17
|
+
from .instruct import (
|
18
|
+
INSTRUCT_FIELD,
|
19
|
+
LIST_INSTRUCT_FIELD_MODEL,
|
20
|
+
Instruct,
|
21
|
+
InstructResponse,
|
22
|
+
)
|
23
|
+
from .reason import REASON_FIELD, Reason
|
13
24
|
|
14
25
|
__all__ = (
|
15
26
|
"ActionRequestModel",
|
@@ -27,4 +38,10 @@ __all__ = (
|
|
27
38
|
"Instruct",
|
28
39
|
"InstructResponse",
|
29
40
|
"Reason",
|
41
|
+
"LIST_INSTRUCT_FIELD_MODEL",
|
42
|
+
"INSTRUCT_FIELD",
|
43
|
+
"ACTION_REQUESTS_FIELD",
|
44
|
+
"ACTION_RESPONSES_FIELD",
|
45
|
+
"ACTION_REQUIRED_FIELD",
|
46
|
+
"REASON_FIELD",
|
30
47
|
)
|
@@ -13,18 +13,16 @@ from pydantic import BaseModel, PydanticUserError
|
|
13
13
|
|
14
14
|
from lionagi.utils import is_import_installed
|
15
15
|
|
16
|
-
_HAS_DATAMODEL_CODE_GENERATOR = is_import_installed("
|
16
|
+
_HAS_DATAMODEL_CODE_GENERATOR = is_import_installed("datamodel_code_generator")
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
from datamodel_code_generator import (
|
18
|
+
try:
|
19
|
+
from datamodel_code_generator import ( # type: ignore[import]
|
21
20
|
DataModelType,
|
22
21
|
InputFileType,
|
23
22
|
PythonVersion,
|
24
23
|
generate,
|
25
24
|
)
|
26
|
-
|
27
|
-
# Create dummy objects for when package is not installed
|
25
|
+
except ImportError:
|
28
26
|
DataModelType = None
|
29
27
|
InputFileType = None
|
30
28
|
PythonVersion = None
|
lionagi/operations/__init__.py
CHANGED
@@ -2,6 +2,21 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
|
+
from .brainstorm.brainstorm import BrainstormOperation, brainstorm
|
6
|
+
from .builder import ExpansionStrategy, OperationGraphBuilder
|
5
7
|
from .flow import flow
|
6
8
|
from .node import BranchOperations, Operation
|
7
|
-
from .
|
9
|
+
from .plan.plan import PlanOperation, plan
|
10
|
+
|
11
|
+
__all__ = (
|
12
|
+
"ExpansionStrategy",
|
13
|
+
"OperationGraphBuilder",
|
14
|
+
"create_operation_graph",
|
15
|
+
"flow",
|
16
|
+
"BranchOperations",
|
17
|
+
"Operation",
|
18
|
+
"plan",
|
19
|
+
"PlanOperation",
|
20
|
+
"brainstorm",
|
21
|
+
"BrainstormOperation",
|
22
|
+
)
|
@@ -0,0 +1,664 @@
|
|
1
|
+
# Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
4
|
+
|
5
|
+
"""
|
6
|
+
OperationGraphBuilder: Incremental graph builder for multi-stage operations.
|
7
|
+
|
8
|
+
Build → Execute → Expand → Execute → ...
|
9
|
+
"""
|
10
|
+
|
11
|
+
from enum import Enum
|
12
|
+
from typing import Any
|
13
|
+
|
14
|
+
from lionagi.operations.node import BranchOperations, Operation
|
15
|
+
from lionagi.protocols.graph.edge import Edge
|
16
|
+
from lionagi.protocols.graph.graph import Graph
|
17
|
+
|
18
|
+
__all__ = (
|
19
|
+
"OperationGraphBuilder",
|
20
|
+
"ExpansionStrategy",
|
21
|
+
)
|
22
|
+
|
23
|
+
|
24
|
+
class ExpansionStrategy(Enum):
|
25
|
+
"""Strategies for expanding operations."""
|
26
|
+
|
27
|
+
CONCURRENT = "concurrent"
|
28
|
+
SEQUENTIAL = "sequential"
|
29
|
+
SEQUENTIAL_CONCURRENT_CHUNK = "sequential_concurrent_chunk"
|
30
|
+
CONCURRENT_SEQUENTIAL_CHUNK = "concurrent_sequential_chunk"
|
31
|
+
|
32
|
+
|
33
|
+
class OperationGraphBuilder:
|
34
|
+
"""
|
35
|
+
Incremental graph builder that supports build → execute → expand cycles.
|
36
|
+
|
37
|
+
Unlike static builders, this maintains state and allows expanding the graph
|
38
|
+
based on execution results.
|
39
|
+
|
40
|
+
Examples:
|
41
|
+
>>> # Build initial graph
|
42
|
+
>>> builder = OperationGraphBuilder()
|
43
|
+
>>> builder.add_operation("operate", instruction="Generate ideas", num_instruct=5)
|
44
|
+
>>> graph = builder.get_graph()
|
45
|
+
>>>
|
46
|
+
>>> # Execute with session
|
47
|
+
>>> result = await session.flow(graph)
|
48
|
+
>>>
|
49
|
+
>>> # Expand based on results
|
50
|
+
>>> if hasattr(result, 'instruct_models'):
|
51
|
+
... builder.expand_from_result(
|
52
|
+
... result.instruct_models,
|
53
|
+
... source_node_id=builder.last_operation_id,
|
54
|
+
... operation="instruct"
|
55
|
+
... )
|
56
|
+
>>>
|
57
|
+
>>> # Get expanded graph and continue execution
|
58
|
+
>>> graph = builder.get_graph()
|
59
|
+
>>> final_result = await session.flow(graph)
|
60
|
+
"""
|
61
|
+
|
62
|
+
def __init__(self, name: str = "DynamicGraph"):
|
63
|
+
"""Initialize the incremental graph builder."""
|
64
|
+
self.name = name
|
65
|
+
self.graph = Graph()
|
66
|
+
|
67
|
+
# Track state
|
68
|
+
self._operations: dict[str, Operation] = {} # All operations by ID
|
69
|
+
self._executed: set[str] = set() # IDs of executed operations
|
70
|
+
self._current_heads: list[str] = [] # Current head nodes for linking
|
71
|
+
self.last_operation_id: str | None = None
|
72
|
+
|
73
|
+
def add_operation(
|
74
|
+
self,
|
75
|
+
operation: BranchOperations,
|
76
|
+
node_id: str | None = None,
|
77
|
+
depends_on: list[str] | None = None,
|
78
|
+
**parameters,
|
79
|
+
) -> str:
|
80
|
+
"""
|
81
|
+
Add an operation to the graph.
|
82
|
+
|
83
|
+
Args:
|
84
|
+
operation: The branch operation
|
85
|
+
node_id: Optional ID reference for this node
|
86
|
+
depends_on: List of node IDs this depends on
|
87
|
+
**parameters: Operation parameters
|
88
|
+
|
89
|
+
Returns:
|
90
|
+
ID of the created node
|
91
|
+
"""
|
92
|
+
# Create operation node
|
93
|
+
node = Operation(operation=operation, parameters=parameters)
|
94
|
+
|
95
|
+
self.graph.add_node(node)
|
96
|
+
self._operations[node.id] = node
|
97
|
+
|
98
|
+
# Store reference if provided
|
99
|
+
if node_id:
|
100
|
+
# Add as metadata for easy lookup
|
101
|
+
node.metadata["reference_id"] = node_id
|
102
|
+
|
103
|
+
# Handle dependencies
|
104
|
+
if depends_on:
|
105
|
+
for dep_id in depends_on:
|
106
|
+
if dep_id in self._operations:
|
107
|
+
edge = Edge(
|
108
|
+
head=dep_id, tail=node.id, label=["depends_on"]
|
109
|
+
)
|
110
|
+
self.graph.add_edge(edge)
|
111
|
+
elif self._current_heads:
|
112
|
+
# Auto-link from current heads
|
113
|
+
for head_id in self._current_heads:
|
114
|
+
edge = Edge(head=head_id, tail=node.id, label=["sequential"])
|
115
|
+
self.graph.add_edge(edge)
|
116
|
+
|
117
|
+
# Update state
|
118
|
+
self._current_heads = [node.id]
|
119
|
+
self.last_operation_id = node.id
|
120
|
+
|
121
|
+
return node.id
|
122
|
+
|
123
|
+
def expand_from_result(
|
124
|
+
self,
|
125
|
+
items: list[Any],
|
126
|
+
source_node_id: str,
|
127
|
+
operation: BranchOperations,
|
128
|
+
strategy: ExpansionStrategy = ExpansionStrategy.CONCURRENT,
|
129
|
+
**shared_params,
|
130
|
+
) -> list[str]:
|
131
|
+
"""
|
132
|
+
Expand the graph based on execution results.
|
133
|
+
|
134
|
+
This is called after executing the graph to add new operations
|
135
|
+
based on results.
|
136
|
+
|
137
|
+
Args:
|
138
|
+
items: Items from result to expand (e.g., instruct_models)
|
139
|
+
source_node_id: ID of node that produced these items
|
140
|
+
operation: Operation to apply to each item
|
141
|
+
strategy: How to organize the expanded operations
|
142
|
+
**shared_params: Shared parameters for all operations
|
143
|
+
|
144
|
+
Returns:
|
145
|
+
List of new node IDs
|
146
|
+
"""
|
147
|
+
if source_node_id not in self._operations:
|
148
|
+
raise ValueError(f"Source node {source_node_id} not found")
|
149
|
+
|
150
|
+
new_node_ids = []
|
151
|
+
|
152
|
+
# Create operation for each item
|
153
|
+
for i, item in enumerate(items):
|
154
|
+
# Extract parameters from item if it's a model
|
155
|
+
if hasattr(item, "model_dump"):
|
156
|
+
params = {**item.model_dump(), **shared_params}
|
157
|
+
else:
|
158
|
+
params = {**shared_params, "item_index": i, "item": str(item)}
|
159
|
+
|
160
|
+
# Add metadata about expansion
|
161
|
+
params["expanded_from"] = source_node_id
|
162
|
+
params["expansion_strategy"] = strategy.value
|
163
|
+
|
164
|
+
node = Operation(
|
165
|
+
operation=operation,
|
166
|
+
parameters=params,
|
167
|
+
metadata={
|
168
|
+
"expansion_index": i,
|
169
|
+
"expansion_source": source_node_id,
|
170
|
+
"expansion_strategy": strategy.value,
|
171
|
+
},
|
172
|
+
)
|
173
|
+
|
174
|
+
self.graph.add_node(node)
|
175
|
+
self._operations[node.id] = node
|
176
|
+
new_node_ids.append(node.id)
|
177
|
+
|
178
|
+
# Link from source
|
179
|
+
edge = Edge(
|
180
|
+
head=source_node_id,
|
181
|
+
tail=node.id,
|
182
|
+
label=["expansion", strategy.value],
|
183
|
+
)
|
184
|
+
self.graph.add_edge(edge)
|
185
|
+
|
186
|
+
# Update current heads based on strategy
|
187
|
+
if strategy in [
|
188
|
+
ExpansionStrategy.CONCURRENT,
|
189
|
+
ExpansionStrategy.SEQUENTIAL,
|
190
|
+
]:
|
191
|
+
self._current_heads = new_node_ids
|
192
|
+
|
193
|
+
return new_node_ids
|
194
|
+
|
195
|
+
def add_aggregation(
|
196
|
+
self,
|
197
|
+
operation: BranchOperations,
|
198
|
+
source_node_ids: list[str] | None = None,
|
199
|
+
**parameters,
|
200
|
+
) -> str:
|
201
|
+
"""
|
202
|
+
Add an aggregation operation that collects from multiple sources.
|
203
|
+
|
204
|
+
Args:
|
205
|
+
operation: Aggregation operation
|
206
|
+
source_node_ids: Nodes to aggregate from (defaults to current heads)
|
207
|
+
**parameters: Operation parameters
|
208
|
+
|
209
|
+
Returns:
|
210
|
+
ID of aggregation node
|
211
|
+
"""
|
212
|
+
sources = source_node_ids or self._current_heads
|
213
|
+
if not sources:
|
214
|
+
raise ValueError("No source nodes for aggregation")
|
215
|
+
|
216
|
+
# Add aggregation metadata
|
217
|
+
agg_params = {
|
218
|
+
"aggregation_sources": sources,
|
219
|
+
"aggregation_count": len(sources),
|
220
|
+
**parameters,
|
221
|
+
}
|
222
|
+
|
223
|
+
node = Operation(
|
224
|
+
operation=operation,
|
225
|
+
parameters=agg_params,
|
226
|
+
metadata={"aggregation": True},
|
227
|
+
)
|
228
|
+
|
229
|
+
self.graph.add_node(node)
|
230
|
+
self._operations[node.id] = node
|
231
|
+
|
232
|
+
# Connect all sources
|
233
|
+
for source_id in sources:
|
234
|
+
edge = Edge(head=source_id, tail=node.id, label=["aggregate"])
|
235
|
+
self.graph.add_edge(edge)
|
236
|
+
|
237
|
+
# Update state
|
238
|
+
self._current_heads = [node.id]
|
239
|
+
self.last_operation_id = node.id
|
240
|
+
|
241
|
+
return node.id
|
242
|
+
|
243
|
+
def mark_executed(self, node_ids: list[str]):
|
244
|
+
"""
|
245
|
+
Mark nodes as executed.
|
246
|
+
|
247
|
+
This helps track which parts of the graph have been run.
|
248
|
+
|
249
|
+
Args:
|
250
|
+
node_ids: IDs of executed nodes
|
251
|
+
"""
|
252
|
+
self._executed.update(node_ids)
|
253
|
+
|
254
|
+
def get_unexecuted_nodes(self) -> list[Operation]:
|
255
|
+
"""
|
256
|
+
Get nodes that haven't been executed yet.
|
257
|
+
|
258
|
+
Returns:
|
259
|
+
List of unexecuted operations
|
260
|
+
"""
|
261
|
+
return [
|
262
|
+
op
|
263
|
+
for op_id, op in self._operations.items()
|
264
|
+
if op_id not in self._executed
|
265
|
+
]
|
266
|
+
|
267
|
+
def add_conditional_branch(
|
268
|
+
self,
|
269
|
+
condition_check_op: BranchOperations,
|
270
|
+
true_op: BranchOperations,
|
271
|
+
false_op: BranchOperations | None = None,
|
272
|
+
**check_params,
|
273
|
+
) -> dict[str, str]:
|
274
|
+
"""
|
275
|
+
Add a conditional branch structure.
|
276
|
+
|
277
|
+
Args:
|
278
|
+
condition_check_op: Operation that evaluates condition
|
279
|
+
true_op: Operation if condition is true
|
280
|
+
false_op: Operation if condition is false
|
281
|
+
**check_params: Parameters for condition check
|
282
|
+
|
283
|
+
Returns:
|
284
|
+
Dict with node IDs: {'check': id, 'true': id, 'false': id}
|
285
|
+
"""
|
286
|
+
# Add condition check node
|
287
|
+
check_node = Operation(
|
288
|
+
operation=condition_check_op,
|
289
|
+
parameters={**check_params, "is_condition_check": True},
|
290
|
+
)
|
291
|
+
self.graph.add_node(check_node)
|
292
|
+
self._operations[check_node.id] = check_node
|
293
|
+
|
294
|
+
# Link from current heads
|
295
|
+
for head_id in self._current_heads:
|
296
|
+
edge = Edge(
|
297
|
+
head=head_id, tail=check_node.id, label=["to_condition"]
|
298
|
+
)
|
299
|
+
self.graph.add_edge(edge)
|
300
|
+
|
301
|
+
result = {"check": check_node.id}
|
302
|
+
|
303
|
+
# Add true branch
|
304
|
+
true_node = Operation(operation=true_op, parameters={"branch": "true"})
|
305
|
+
self.graph.add_node(true_node)
|
306
|
+
self._operations[true_node.id] = true_node
|
307
|
+
result["true"] = true_node.id
|
308
|
+
|
309
|
+
# Connect with condition label
|
310
|
+
true_edge = Edge(
|
311
|
+
head=check_node.id, tail=true_node.id, label=["if_true"]
|
312
|
+
)
|
313
|
+
self.graph.add_edge(true_edge)
|
314
|
+
|
315
|
+
# Add false branch if specified
|
316
|
+
if false_op:
|
317
|
+
false_node = Operation(
|
318
|
+
operation=false_op, parameters={"branch": "false"}
|
319
|
+
)
|
320
|
+
self.graph.add_node(false_node)
|
321
|
+
self._operations[false_node.id] = false_node
|
322
|
+
result["false"] = false_node.id
|
323
|
+
|
324
|
+
false_edge = Edge(
|
325
|
+
head=check_node.id, tail=false_node.id, label=["if_false"]
|
326
|
+
)
|
327
|
+
self.graph.add_edge(false_edge)
|
328
|
+
|
329
|
+
self._current_heads = [true_node.id, false_node.id]
|
330
|
+
else:
|
331
|
+
self._current_heads = [true_node.id]
|
332
|
+
|
333
|
+
return result
|
334
|
+
|
335
|
+
def get_graph(self) -> Graph:
|
336
|
+
"""
|
337
|
+
Get the current graph for execution.
|
338
|
+
|
339
|
+
Returns:
|
340
|
+
The graph in its current state
|
341
|
+
"""
|
342
|
+
return self.graph
|
343
|
+
|
344
|
+
def get_node_by_reference(self, reference_id: str) -> Operation | None:
|
345
|
+
"""
|
346
|
+
Get a node by its reference ID.
|
347
|
+
|
348
|
+
Args:
|
349
|
+
reference_id: The reference ID assigned when creating the node
|
350
|
+
|
351
|
+
Returns:
|
352
|
+
The operation node or None
|
353
|
+
"""
|
354
|
+
for op in self._operations.values():
|
355
|
+
if op.metadata.get("reference_id") == reference_id:
|
356
|
+
return op
|
357
|
+
return None
|
358
|
+
|
359
|
+
def visualize_state(self) -> dict[str, Any]:
|
360
|
+
"""
|
361
|
+
Get visualization of current graph state.
|
362
|
+
|
363
|
+
Returns:
|
364
|
+
Dict with graph statistics and state
|
365
|
+
"""
|
366
|
+
# Group nodes by expansion source
|
367
|
+
expansions = {}
|
368
|
+
for op in self._operations.values():
|
369
|
+
source = op.metadata.get("expansion_source")
|
370
|
+
if source:
|
371
|
+
if source not in expansions:
|
372
|
+
expansions[source] = []
|
373
|
+
expansions[source].append(op.id)
|
374
|
+
|
375
|
+
return {
|
376
|
+
"name": self.name,
|
377
|
+
"total_nodes": len(self._operations),
|
378
|
+
"executed_nodes": len(self._executed),
|
379
|
+
"unexecuted_nodes": len(self._operations) - len(self._executed),
|
380
|
+
"current_heads": self._current_heads,
|
381
|
+
"expansions": expansions,
|
382
|
+
"edges": len(self.graph.internal_edges),
|
383
|
+
}
|
384
|
+
|
385
|
+
def visualize(self, title: str = "Operation Graph", figsize=(14, 10)):
|
386
|
+
visualize_graph(
|
387
|
+
self,
|
388
|
+
title=title,
|
389
|
+
figsize=figsize,
|
390
|
+
)
|
391
|
+
|
392
|
+
|
393
|
+
def visualize_graph(
|
394
|
+
builder: OperationGraphBuilder,
|
395
|
+
title: str = "Operation Graph",
|
396
|
+
figsize=(14, 10),
|
397
|
+
):
|
398
|
+
"""Visualization with improved layout for complex graphs."""
|
399
|
+
import matplotlib.pyplot as plt
|
400
|
+
import networkx as nx
|
401
|
+
import numpy as np
|
402
|
+
|
403
|
+
graph = builder.get_graph()
|
404
|
+
|
405
|
+
# Convert to networkx
|
406
|
+
G = nx.DiGraph()
|
407
|
+
|
408
|
+
# Track node positions for hierarchical layout
|
409
|
+
node_levels = {}
|
410
|
+
node_labels = {}
|
411
|
+
node_colors = []
|
412
|
+
node_sizes = []
|
413
|
+
|
414
|
+
# First pass: add nodes and determine levels
|
415
|
+
for node in graph.internal_nodes.values():
|
416
|
+
node_id = str(node.id)[:8]
|
417
|
+
G.add_node(node_id)
|
418
|
+
|
419
|
+
# Determine level based on dependencies
|
420
|
+
in_edges = [
|
421
|
+
e
|
422
|
+
for e in graph.internal_edges.values()
|
423
|
+
if str(e.tail)[:8] == node_id
|
424
|
+
]
|
425
|
+
if not in_edges:
|
426
|
+
level = 0 # Root nodes
|
427
|
+
else:
|
428
|
+
# Get max level of predecessors + 1
|
429
|
+
pred_levels = []
|
430
|
+
for edge in in_edges:
|
431
|
+
pred_id = str(edge.head)[:8]
|
432
|
+
if pred_id in node_levels:
|
433
|
+
pred_levels.append(node_levels[pred_id])
|
434
|
+
level = max(pred_levels, default=0) + 1
|
435
|
+
|
436
|
+
node_levels[node_id] = level
|
437
|
+
|
438
|
+
# Create label
|
439
|
+
ref_id = node.metadata.get("reference_id", "")
|
440
|
+
if ref_id:
|
441
|
+
label = f"{node.operation}\n[{ref_id}]"
|
442
|
+
else:
|
443
|
+
label = f"{node.operation}\n{node_id}"
|
444
|
+
node_labels[node_id] = label
|
445
|
+
|
446
|
+
# Color and size based on status and type
|
447
|
+
if node.id in builder._executed:
|
448
|
+
node_colors.append("#90EE90") # Light green
|
449
|
+
node_sizes.append(4000)
|
450
|
+
elif node.metadata.get("expansion_source"):
|
451
|
+
node_colors.append("#87CEEB") # Sky blue
|
452
|
+
node_sizes.append(3500)
|
453
|
+
elif node.metadata.get("aggregation"):
|
454
|
+
node_colors.append("#FFD700") # Gold
|
455
|
+
node_sizes.append(4500)
|
456
|
+
elif node.metadata.get("is_condition_check"):
|
457
|
+
node_colors.append("#DDA0DD") # Plum
|
458
|
+
node_sizes.append(3500)
|
459
|
+
else:
|
460
|
+
node_colors.append("#E0E0E0") # Light gray
|
461
|
+
node_sizes.append(3000)
|
462
|
+
|
463
|
+
# Add edges
|
464
|
+
edge_colors = []
|
465
|
+
edge_styles = []
|
466
|
+
edge_widths = []
|
467
|
+
edge_labels = {}
|
468
|
+
|
469
|
+
for edge in graph.internal_edges.values():
|
470
|
+
head_id = str(edge.head)[:8]
|
471
|
+
tail_id = str(edge.tail)[:8]
|
472
|
+
G.add_edge(head_id, tail_id)
|
473
|
+
|
474
|
+
# Style edges based on type
|
475
|
+
edge_label = edge.label[0] if edge.label else ""
|
476
|
+
edge_labels[(head_id, tail_id)] = edge_label
|
477
|
+
|
478
|
+
if "expansion" in edge_label:
|
479
|
+
edge_colors.append("#4169E1") # Royal blue
|
480
|
+
edge_styles.append("dashed")
|
481
|
+
edge_widths.append(2)
|
482
|
+
elif "aggregate" in edge_label:
|
483
|
+
edge_colors.append("#FF6347") # Tomato
|
484
|
+
edge_styles.append("dotted")
|
485
|
+
edge_widths.append(2.5)
|
486
|
+
else:
|
487
|
+
edge_colors.append("#808080") # Gray
|
488
|
+
edge_styles.append("solid")
|
489
|
+
edge_widths.append(1.5)
|
490
|
+
|
491
|
+
# Create improved hierarchical layout
|
492
|
+
pos = {}
|
493
|
+
nodes_by_level = {}
|
494
|
+
|
495
|
+
for node_id, level in node_levels.items():
|
496
|
+
if level not in nodes_by_level:
|
497
|
+
nodes_by_level[level] = []
|
498
|
+
nodes_by_level[level].append(node_id)
|
499
|
+
|
500
|
+
# Position nodes with better spacing algorithm
|
501
|
+
y_spacing = 2.5
|
502
|
+
max_width = 16 # Maximum horizontal spread
|
503
|
+
|
504
|
+
for level, nodes in nodes_by_level.items():
|
505
|
+
num_nodes = len(nodes)
|
506
|
+
|
507
|
+
if num_nodes <= 6:
|
508
|
+
# Normal spacing for small levels
|
509
|
+
x_spacing = 2.5
|
510
|
+
x_offset = -(num_nodes - 1) * x_spacing / 2
|
511
|
+
for i, node_id in enumerate(nodes):
|
512
|
+
pos[node_id] = (x_offset + i * x_spacing, -level * y_spacing)
|
513
|
+
else:
|
514
|
+
# Multi-row layout for large levels
|
515
|
+
nodes_per_row = min(6, int(np.ceil(np.sqrt(num_nodes * 1.5))))
|
516
|
+
rows = int(np.ceil(num_nodes / nodes_per_row))
|
517
|
+
|
518
|
+
for i, node_id in enumerate(nodes):
|
519
|
+
row = i // nodes_per_row
|
520
|
+
col = i % nodes_per_row
|
521
|
+
|
522
|
+
# Calculate row width
|
523
|
+
nodes_in_row = min(
|
524
|
+
nodes_per_row, num_nodes - row * nodes_per_row
|
525
|
+
)
|
526
|
+
x_spacing = 2.5
|
527
|
+
x_offset = -(nodes_in_row - 1) * x_spacing / 2
|
528
|
+
|
529
|
+
# Add slight y offset for different rows
|
530
|
+
y_offset = row * 0.8
|
531
|
+
|
532
|
+
pos[node_id] = (
|
533
|
+
x_offset + col * x_spacing,
|
534
|
+
-level * y_spacing - y_offset,
|
535
|
+
)
|
536
|
+
|
537
|
+
# Create figure
|
538
|
+
plt.figure(figsize=figsize)
|
539
|
+
|
540
|
+
# Draw nodes
|
541
|
+
nx.draw_networkx_nodes(
|
542
|
+
G,
|
543
|
+
pos,
|
544
|
+
node_color=node_colors,
|
545
|
+
node_size=node_sizes,
|
546
|
+
alpha=0.9,
|
547
|
+
linewidths=2,
|
548
|
+
edgecolors="black",
|
549
|
+
)
|
550
|
+
|
551
|
+
# Draw edges with different styles - use curved edges for better visibility
|
552
|
+
for i, (u, v) in enumerate(G.edges()):
|
553
|
+
# Calculate curve based on node positions
|
554
|
+
u_pos = pos[u]
|
555
|
+
v_pos = pos[v]
|
556
|
+
|
557
|
+
# Determine connection style based on relative positions
|
558
|
+
if abs(u_pos[0] - v_pos[0]) > 5: # Far apart horizontally
|
559
|
+
connectionstyle = "arc3,rad=0.2"
|
560
|
+
else:
|
561
|
+
connectionstyle = "arc3,rad=0.1"
|
562
|
+
|
563
|
+
nx.draw_networkx_edges(
|
564
|
+
G,
|
565
|
+
pos,
|
566
|
+
[(u, v)],
|
567
|
+
edge_color=[edge_colors[i]],
|
568
|
+
style=edge_styles[i],
|
569
|
+
width=edge_widths[i],
|
570
|
+
alpha=0.7,
|
571
|
+
arrows=True,
|
572
|
+
arrowsize=20,
|
573
|
+
arrowstyle="-|>",
|
574
|
+
connectionstyle=connectionstyle,
|
575
|
+
)
|
576
|
+
|
577
|
+
# Draw labels
|
578
|
+
nx.draw_networkx_labels(
|
579
|
+
G,
|
580
|
+
pos,
|
581
|
+
node_labels,
|
582
|
+
font_size=9,
|
583
|
+
font_weight="bold",
|
584
|
+
font_family="monospace",
|
585
|
+
)
|
586
|
+
|
587
|
+
# Draw edge labels (only for smaller graphs)
|
588
|
+
if len(G.edges()) < 20:
|
589
|
+
nx.draw_networkx_edge_labels(
|
590
|
+
G,
|
591
|
+
pos,
|
592
|
+
edge_labels,
|
593
|
+
font_size=7,
|
594
|
+
font_color="darkblue",
|
595
|
+
bbox=dict(
|
596
|
+
boxstyle="round,pad=0.3",
|
597
|
+
facecolor="white",
|
598
|
+
edgecolor="none",
|
599
|
+
alpha=0.7,
|
600
|
+
),
|
601
|
+
)
|
602
|
+
|
603
|
+
plt.title(title, fontsize=18, fontweight="bold", pad=20)
|
604
|
+
plt.axis("off")
|
605
|
+
|
606
|
+
# Enhanced legend
|
607
|
+
from matplotlib.lines import Line2D
|
608
|
+
from matplotlib.patches import Patch, Rectangle
|
609
|
+
|
610
|
+
legend_elements = [
|
611
|
+
Patch(facecolor="#90EE90", edgecolor="black", label="Executed"),
|
612
|
+
Patch(facecolor="#87CEEB", edgecolor="black", label="Expanded"),
|
613
|
+
Patch(facecolor="#FFD700", edgecolor="black", label="Aggregation"),
|
614
|
+
Patch(facecolor="#DDA0DD", edgecolor="black", label="Condition"),
|
615
|
+
Patch(facecolor="#E0E0E0", edgecolor="black", label="Pending"),
|
616
|
+
Line2D([0], [0], color="#808080", linewidth=2, label="Sequential"),
|
617
|
+
Line2D(
|
618
|
+
[0],
|
619
|
+
[0],
|
620
|
+
color="#4169E1",
|
621
|
+
linewidth=2,
|
622
|
+
linestyle="dashed",
|
623
|
+
label="Expansion",
|
624
|
+
),
|
625
|
+
Line2D(
|
626
|
+
[0],
|
627
|
+
[0],
|
628
|
+
color="#FF6347",
|
629
|
+
linewidth=2,
|
630
|
+
linestyle="dotted",
|
631
|
+
label="Aggregate",
|
632
|
+
),
|
633
|
+
]
|
634
|
+
|
635
|
+
plt.legend(
|
636
|
+
handles=legend_elements,
|
637
|
+
loc="upper left",
|
638
|
+
bbox_to_anchor=(0, 1),
|
639
|
+
frameon=True,
|
640
|
+
fancybox=True,
|
641
|
+
shadow=True,
|
642
|
+
ncol=2,
|
643
|
+
)
|
644
|
+
|
645
|
+
# Add statistics box
|
646
|
+
stats_text = f"Nodes: {len(G.nodes())}\nEdges: {len(G.edges())}\nExecuted: {len(builder._executed)}"
|
647
|
+
if nodes_by_level:
|
648
|
+
max_level = max(nodes_by_level.keys())
|
649
|
+
stats_text += f"\nLevels: {max_level + 1}"
|
650
|
+
|
651
|
+
plt.text(
|
652
|
+
0.98,
|
653
|
+
0.02,
|
654
|
+
stats_text,
|
655
|
+
transform=plt.gca().transAxes,
|
656
|
+
bbox=dict(boxstyle="round,pad=0.5", facecolor="lightgray", alpha=0.8),
|
657
|
+
verticalalignment="bottom",
|
658
|
+
horizontalalignment="right",
|
659
|
+
fontsize=10,
|
660
|
+
fontfamily="monospace",
|
661
|
+
)
|
662
|
+
|
663
|
+
plt.tight_layout()
|
664
|
+
plt.show()
|
lionagi/operations/flow.py
CHANGED
@@ -3,10 +3,12 @@
|
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
5
|
import asyncio
|
6
|
+
import contextlib
|
6
7
|
from typing import Any
|
7
8
|
|
8
9
|
from lionagi.operations.node import Operation
|
9
|
-
from lionagi.
|
10
|
+
from lionagi.operations.utils import prepare_session
|
11
|
+
from lionagi.protocols.types import ID, Edge, Graph, Node
|
10
12
|
from lionagi.session.branch import Branch
|
11
13
|
from lionagi.session.session import Session
|
12
14
|
from lionagi.utils import to_dict
|
@@ -44,19 +46,10 @@ async def flow(
|
|
44
46
|
if not graph.is_acyclic():
|
45
47
|
raise ValueError("Graph must be acyclic for flow execution")
|
46
48
|
|
47
|
-
|
49
|
+
session, branch = prepare_session(session, branch)
|
48
50
|
if not parallel or max_concurrent == 1:
|
49
51
|
return await _execute_sequential(branch, graph, context, verbose)
|
50
52
|
|
51
|
-
# Parallel execution using session
|
52
|
-
if session is None:
|
53
|
-
# Create temporary session for this flow
|
54
|
-
from lionagi.session.session import Session
|
55
|
-
|
56
|
-
session = Session()
|
57
|
-
session.branches.include(branch)
|
58
|
-
session.default_branch = branch
|
59
|
-
|
60
53
|
return await _execute_parallel(
|
61
54
|
session, graph, context, max_concurrent, verbose
|
62
55
|
)
|
@@ -167,7 +160,7 @@ async def _execute_parallel(
|
|
167
160
|
|
168
161
|
# Process nodes in dependency order
|
169
162
|
remaining_nodes = {node.id for node in operation_nodes}
|
170
|
-
executing_tasks = {}
|
163
|
+
executing_tasks: dict[ID[Operation], asyncio.Task] = {}
|
171
164
|
blocked_nodes = set() # Nodes that have been checked and found blocked
|
172
165
|
|
173
166
|
max_iterations = 1000 # Prevent infinite loops
|
@@ -392,7 +385,7 @@ async def _dependencies_satisfied_async(
|
|
392
385
|
) -> bool:
|
393
386
|
"""Check if node dependencies are satisfied and edge conditions pass."""
|
394
387
|
# Get all incoming edges to this node
|
395
|
-
incoming_edges = []
|
388
|
+
incoming_edges: list[Edge] = []
|
396
389
|
for edge in graph.internal_edges:
|
397
390
|
if edge.tail == node.id:
|
398
391
|
incoming_edges.append(edge)
|
@@ -406,10 +399,6 @@ async def _dependencies_satisfied_async(
|
|
406
399
|
for edge in incoming_edges:
|
407
400
|
# Check if predecessor is completed
|
408
401
|
if edge.head not in completed:
|
409
|
-
# If edge has no condition, we need to wait for predecessor
|
410
|
-
if not edge.condition:
|
411
|
-
continue
|
412
|
-
# If edge has condition but predecessor not complete, skip
|
413
402
|
continue
|
414
403
|
|
415
404
|
# Predecessor is completed
|
@@ -423,12 +412,9 @@ async def _dependencies_satisfied_async(
|
|
423
412
|
result_value = to_dict(result_value, recursive=True)
|
424
413
|
|
425
414
|
ctx = {"result": result_value, "context": execution_context or {}}
|
426
|
-
|
415
|
+
with contextlib.suppress(Exception):
|
427
416
|
if await edge.condition.apply(ctx):
|
428
417
|
at_least_one_satisfied = True
|
429
|
-
except Exception as e:
|
430
|
-
# Condition evaluation failed
|
431
|
-
continue
|
432
418
|
else:
|
433
419
|
# No condition, edge is satisfied
|
434
420
|
at_least_one_satisfied = True
|
lionagi/operations/utils.py
CHANGED
@@ -7,7 +7,9 @@ from lionagi.session.session import Branch, Session
|
|
7
7
|
|
8
8
|
|
9
9
|
def prepare_session(
|
10
|
-
session
|
10
|
+
session: Session | None = None,
|
11
|
+
branch: Branch | None = None,
|
12
|
+
branch_kwargs=None,
|
11
13
|
) -> tuple[Session, Branch]:
|
12
14
|
if session is not None:
|
13
15
|
if branch is not None:
|
@@ -2,6 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
|
+
import logging
|
5
6
|
import os
|
6
7
|
from typing import Any, TypeVar
|
7
8
|
|
@@ -17,6 +18,9 @@ from pydantic import (
|
|
17
18
|
|
18
19
|
from .header_factory import AUTH_TYPES
|
19
20
|
|
21
|
+
logger = logging.getLogger(__name__)
|
22
|
+
|
23
|
+
|
20
24
|
B = TypeVar("B", bound=type[BaseModel])
|
21
25
|
|
22
26
|
|
@@ -32,7 +36,7 @@ class EndpointConfig(BaseModel):
|
|
32
36
|
auth_type: AUTH_TYPES = "bearer"
|
33
37
|
default_headers: dict = {}
|
34
38
|
request_options: B | None = None
|
35
|
-
api_key: str | SecretStr | None = None
|
39
|
+
api_key: str | SecretStr | None = Field(None, exclude=True)
|
36
40
|
timeout: int = 300
|
37
41
|
max_retries: int = 3
|
38
42
|
openai_compatible: bool = False
|
@@ -98,9 +102,16 @@ class EndpointConfig(BaseModel):
|
|
98
102
|
return v.__class__
|
99
103
|
if isinstance(v, dict | str):
|
100
104
|
from lionagi.libs.schema.load_pydantic_model_from_schema import (
|
105
|
+
_HAS_DATAMODEL_CODE_GENERATOR,
|
101
106
|
load_pydantic_model_from_schema,
|
102
107
|
)
|
103
108
|
|
109
|
+
if not _HAS_DATAMODEL_CODE_GENERATOR:
|
110
|
+
logger.warning(
|
111
|
+
"datamodel-code-generator is not installed, "
|
112
|
+
"request_options will not be validated"
|
113
|
+
)
|
114
|
+
return None
|
104
115
|
return load_pydantic_model_from_schema(v)
|
105
116
|
except Exception as e:
|
106
117
|
raise ValueError("Invalid request options") from e
|
lionagi/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "0.13.
|
1
|
+
__version__ = "0.13.6"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: lionagi
|
3
|
-
Version: 0.13.
|
3
|
+
Version: 0.13.6
|
4
4
|
Summary: An Intelligence Operating System.
|
5
5
|
Author-email: HaiyangLi <quantocean.li@gmail.com>, Liangbingyan Luo <llby_luo@outlook.com>
|
6
6
|
License: Apache License
|
@@ -235,6 +235,7 @@ Requires-Dist: tiktoken>=0.8.0
|
|
235
235
|
Requires-Dist: toml>=0.9.0
|
236
236
|
Provides-Extra: all
|
237
237
|
Requires-Dist: claude-code-sdk>=0.0.14; extra == 'all'
|
238
|
+
Requires-Dist: datamodel-code-generator>=0.31.2; extra == 'all'
|
238
239
|
Requires-Dist: docling>=2.15.1; extra == 'all'
|
239
240
|
Requires-Dist: fastmcp>=2.10.5; extra == 'all'
|
240
241
|
Requires-Dist: ollama>=0.4.0; extra == 'all'
|
@@ -257,6 +258,8 @@ Provides-Extra: reader
|
|
257
258
|
Requires-Dist: docling>=2.15.1; extra == 'reader'
|
258
259
|
Provides-Extra: rich
|
259
260
|
Requires-Dist: rich>=13.0.0; extra == 'rich'
|
261
|
+
Provides-Extra: schema
|
262
|
+
Requires-Dist: datamodel-code-generator>=0.31.2; extra == 'schema'
|
260
263
|
Provides-Extra: test
|
261
264
|
Requires-Dist: pytest-asyncio>=1.0.0; extra == 'test'
|
262
265
|
Requires-Dist: pytest>=8.3.4; extra == 'test'
|
@@ -422,8 +425,6 @@ model = iModel(
|
|
422
425
|
# Start a coding session
|
423
426
|
branch = Branch(chat_model=model)
|
424
427
|
response = await branch.communicate("Explain the architecture of protocols, operations, and branch")
|
425
|
-
|
426
|
-
# Claude Code maintains session context automatically
|
427
428
|
response2 = await branch.communicate("how do these parts form lionagi system")
|
428
429
|
```
|
429
430
|
|
@@ -1,13 +1,13 @@
|
|
1
|
-
lionagi/__init__.py,sha256=
|
1
|
+
lionagi/__init__.py,sha256=x_DLjvYZp15u2L3pjIKrUDvvdDBzf7VmrhYVzbsACjU,725
|
2
2
|
lionagi/_class_registry.py,sha256=pfUO1DjFZIqr3OwnNMkFqL_fiEBrrf8-swkGmP_KDLE,3112
|
3
3
|
lionagi/_errors.py,sha256=S02keQTY2IMkTvpLe00v7P7b8QNJ0PrZ1KWmQWCEQAA,500
|
4
|
-
lionagi/_types.py,sha256=
|
4
|
+
lionagi/_types.py,sha256=R5-XbcOpgqDBgwa65EQTC8irPDuLm3oGXY5t_zwpa9M,163
|
5
5
|
lionagi/config.py,sha256=Dxs5FA9UCv1YX5H54qOJcPsDrIF9wFokWEPZ212eH-k,3715
|
6
6
|
lionagi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
7
|
lionagi/settings.py,sha256=HDuKCEJCpc4HudKodBnhoQUGuTGhRHdlIFhbtf3VBtY,1633
|
8
8
|
lionagi/utils.py,sha256=8zCdJHKbDJv2WSzAAiFnMSpvfyZb9RnmfSNaMEqdTJE,79003
|
9
|
-
lionagi/version.py,sha256=
|
10
|
-
lionagi/fields/__init__.py,sha256=
|
9
|
+
lionagi/version.py,sha256=riz4KLyxI3rKxqm-AbvFFuR22uDgmXnMIjs0NxKBiIE,23
|
10
|
+
lionagi/fields/__init__.py,sha256=yrn9NDAM6_v73kK7aJeb-Pvqigeu8WASaV-My-6CDsc,939
|
11
11
|
lionagi/fields/action.py,sha256=OziEpbaUeEVo34KdtbzDxXJBgkf3QLxlcKIQAfHe4O0,5791
|
12
12
|
lionagi/fields/base.py,sha256=5CJc7j8kTTWzXwpYzkSAFzx4BglABfx3AElIATKB7bg,3857
|
13
13
|
lionagi/fields/code.py,sha256=TFym51obzaSfCmeRoHZJyBtjfDI4tvl9F-1sjFc9rMw,7713
|
@@ -46,7 +46,7 @@ lionagi/libs/schema/extract_code_block.py,sha256=PuJbJj1JnqR5fSZudowPcVPpEoKISLr
|
|
46
46
|
lionagi/libs/schema/extract_docstring.py,sha256=uWyUevXS4JSN60tfouoBBAyE4_jyE-fz45CiS-fvKeI,5714
|
47
47
|
lionagi/libs/schema/function_to_schema.py,sha256=XAB031WbYu3a7eFJyYjXVMAjmtWYSYr5kC_DYgjiuyM,5604
|
48
48
|
lionagi/libs/schema/json_schema.py,sha256=cuHcaMr748O9g6suNGmRx4tRXcidd5-c7AMGjTIZyHM,7670
|
49
|
-
lionagi/libs/schema/load_pydantic_model_from_schema.py,sha256=
|
49
|
+
lionagi/libs/schema/load_pydantic_model_from_schema.py,sha256=p4UTgGcb2Tmxc9tLznHPSOWXnHeztJLpl6XTSDcIZ90,10078
|
50
50
|
lionagi/libs/token_transform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
51
51
|
lionagi/libs/token_transform/base.py,sha256=LBnaDgi4HNgaJJGwIzWcQjVMdu49i_93rRvOvMU22Rw,1545
|
52
52
|
lionagi/libs/token_transform/llmlingua.py,sha256=DkeLUlrb7rGx3nZ04aADU9HXXu5mZTf_DBwT0xhzIv4,7
|
@@ -82,12 +82,13 @@ lionagi/models/model_params.py,sha256=zVU-PHp3skjK5ZVjpsPs1k_VJiS8X0hgct0xs6Z6W_
|
|
82
82
|
lionagi/models/note.py,sha256=okWJL4mGqt0bUVxHRyqsfJr7tEh6wwgYhF1CegxudIA,12202
|
83
83
|
lionagi/models/operable_model.py,sha256=fXbcpBjO-SoaeF8fn-F1_KIcYw9_L73VIUM1BDg5hj4,19905
|
84
84
|
lionagi/models/schema_model.py,sha256=ghRIM8aBNaToAknwNlhQKpuKXcwzyCw5pDE31bVKxs0,667
|
85
|
-
lionagi/operations/__init__.py,sha256=
|
86
|
-
lionagi/operations/
|
85
|
+
lionagi/operations/__init__.py,sha256=L22n8rRls9oVdzHoDlznHFGiKJMNw3ZhbwVQbm1Fn6M,584
|
86
|
+
lionagi/operations/builder.py,sha256=6OEPQuONlJuC7bkrmaxOrurMdygjSsvwEX_Zsqf1EmM,20300
|
87
|
+
lionagi/operations/flow.py,sha256=o_o_UTXvW1MRvsCwbIXG5pbJPEvLA0d3Qb7Fk3wRHF4,14627
|
87
88
|
lionagi/operations/manager.py,sha256=7KD6NMWqYJHCPI2LumDRwGinF8WYKFjrr3bsNUi9xzI,564
|
88
89
|
lionagi/operations/node.py,sha256=JNJpn_LUP_46F7C8DcvwAg6rzlaRKzs9RcVGQakARyU,3066
|
89
90
|
lionagi/operations/types.py,sha256=fM8HphnbBifMzhoKKvdl3JxGCBHlEGPJEYkLWj9b7vE,704
|
90
|
-
lionagi/operations/utils.py,sha256=
|
91
|
+
lionagi/operations/utils.py,sha256=b8HmpF5vRgmf6PTzg3_fZCIKMnhoGa0HCyOlX6JCz7g,1263
|
91
92
|
lionagi/operations/ReAct/ReAct.py,sha256=uoJnFMoPP1kzzmgLDFNBwEbWdfGNfG37IT22N1AM-hE,13504
|
92
93
|
lionagi/operations/ReAct/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
|
93
94
|
lionagi/operations/ReAct/utils.py,sha256=FKb0v-1tboN17imxef9jLKWhet0Iz049eqvZCcJKNX8,4436
|
@@ -174,7 +175,7 @@ lionagi/service/types.py,sha256=6zavqBxK1Fj0nB9eZgJn3JICxmdT-n0nn8YWZFzM5LU,508
|
|
174
175
|
lionagi/service/connections/__init__.py,sha256=yHQZ7OJpCftd6CStYR8inbxjJydYdmv9kCvbUBhJ2zU,362
|
175
176
|
lionagi/service/connections/api_calling.py,sha256=XetCrjMhOHNKGGv-NzHhBhVS7XjKPalrS_iExzU-4S4,8005
|
176
177
|
lionagi/service/connections/endpoint.py,sha256=yNIjq9wETMnytynGbq3qY_dkyaMlaHrcfiZjS-tnmLg,14756
|
177
|
-
lionagi/service/connections/endpoint_config.py,sha256=
|
178
|
+
lionagi/service/connections/endpoint_config.py,sha256=7u5HDWe-4nttG2cDXtx_OxPzAI4DAA0bPtjJ6BA4gk8,5162
|
178
179
|
lionagi/service/connections/header_factory.py,sha256=22sG4ian3MiNklF6SdQqkEYgtWKOZik_yDE0Lna6BiE,1754
|
179
180
|
lionagi/service/connections/match_endpoint.py,sha256=K3I4vU6GH6utlEArlyDFUmNdnp94CEPxqKrehAx29J4,2410
|
180
181
|
lionagi/service/connections/providers/__init__.py,sha256=3lzOakDoBWmMaNnT2g-YwktPKa_Wme4lnPRSmOQfayY,105
|
@@ -201,7 +202,7 @@ lionagi/tools/types.py,sha256=XtJLY0m-Yi_ZLWhm0KycayvqMCZd--HxfQ0x9vFUYDE,230
|
|
201
202
|
lionagi/tools/file/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
|
202
203
|
lionagi/tools/file/reader.py,sha256=0TdnfVGVCKuM58MmGM-NyVjhU9BFoitkNYEepdc0z_Y,9529
|
203
204
|
lionagi/tools/memory/tools.py,sha256=zTGBenVsF8Wuh303kWntmQSGlAFKonHNdh5ePuQ26KE,15948
|
204
|
-
lionagi-0.13.
|
205
|
-
lionagi-0.13.
|
206
|
-
lionagi-0.13.
|
207
|
-
lionagi-0.13.
|
205
|
+
lionagi-0.13.6.dist-info/METADATA,sha256=ENE6dEOAAy0IbJkdVVgryZ8v-ySobfMqzgdsZguQsJE,20818
|
206
|
+
lionagi-0.13.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
207
|
+
lionagi-0.13.6.dist-info/licenses/LICENSE,sha256=VXFWsdoN5AAknBCgFqQNgPWYx7OPp-PFEP961zGdOjc,11288
|
208
|
+
lionagi-0.13.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|