lionagi 0.5.3__py3-none-any.whl → 0.5.4__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/core/session/session.py +3 -3
- lionagi/libs/func/async_calls/alcall.py +7 -0
- lionagi/operations/brainstorm/brainstorm.py +318 -93
- lionagi/operations/plan/plan.py +280 -67
- lionagi/version.py +1 -1
- {lionagi-0.5.3.dist-info → lionagi-0.5.4.dist-info}/METADATA +1 -1
- {lionagi-0.5.3.dist-info → lionagi-0.5.4.dist-info}/RECORD +9 -9
- {lionagi-0.5.3.dist-info → lionagi-0.5.4.dist-info}/WHEEL +0 -0
- {lionagi-0.5.3.dist-info → lionagi-0.5.4.dist-info}/licenses/LICENSE +0 -0
lionagi/core/session/session.py
CHANGED
@@ -128,9 +128,9 @@ class Session(Component):
|
|
128
128
|
branch: The branch to set as default or its identifier.
|
129
129
|
"""
|
130
130
|
branch = self.branches[branch]
|
131
|
-
if
|
132
|
-
|
133
|
-
|
131
|
+
if not isinstance(branch, Branch):
|
132
|
+
raise ValueError("Input value for branch is not a valid branch.")
|
133
|
+
self.default_branch = branch
|
134
134
|
|
135
135
|
def to_df(self, branches: ID.RefSeq = None) -> pd.DataFrame:
|
136
136
|
out = self.concat_messages(branches=branches)
|
@@ -148,6 +148,13 @@ async def alcall(
|
|
148
148
|
ucall(func, i, **kwargs), retry_timeout
|
149
149
|
)
|
150
150
|
return index, result
|
151
|
+
|
152
|
+
except InterruptedError:
|
153
|
+
return index, None
|
154
|
+
|
155
|
+
except asyncio.CancelledError:
|
156
|
+
return index, None
|
157
|
+
|
151
158
|
except TimeoutError as e:
|
152
159
|
raise TimeoutError(
|
153
160
|
f"{error_msg or ''} Timeout {retry_timeout} seconds "
|
@@ -2,6 +2,8 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
|
+
import logging
|
6
|
+
from typing import Literal
|
5
7
|
|
6
8
|
from lionagi.core.session.branch import Branch
|
7
9
|
from lionagi.core.session.session import Session
|
@@ -17,13 +19,41 @@ from lionagi.protocols.operatives.instruct import (
|
|
17
19
|
from ..utils import prepare_instruct, prepare_session
|
18
20
|
from .prompt import PROMPT
|
19
21
|
|
22
|
+
# ---------------------------------------------------------------------
|
23
|
+
# Data Models & Utilities
|
24
|
+
# ---------------------------------------------------------------------
|
25
|
+
|
20
26
|
|
21
27
|
class BrainstormOperation(BaseModel):
|
28
|
+
"""
|
29
|
+
Container for the outcomes of a brainstorming session:
|
30
|
+
1. initial: the initial result of the 'brainstorm' prompt
|
31
|
+
2. brainstorm: the results of auto-run instructions (if auto_run = True)
|
32
|
+
3. explore: the results of exploring those instructions (if auto_explore = True)
|
33
|
+
"""
|
34
|
+
|
22
35
|
initial: Any
|
23
36
|
brainstorm: list[Instruct] | None = None
|
24
37
|
explore: list[InstructResponse] | None = None
|
25
38
|
|
26
39
|
|
40
|
+
def chunked(iterable, n):
|
41
|
+
"""
|
42
|
+
Yield successive n-sized chunks from an iterable.
|
43
|
+
|
44
|
+
Example:
|
45
|
+
>>> list(chunked([1,2,3,4,5], 2))
|
46
|
+
[[1,2],[3,4],[5]]
|
47
|
+
"""
|
48
|
+
for i in range(0, len(iterable), n):
|
49
|
+
yield iterable[i : i + n]
|
50
|
+
|
51
|
+
|
52
|
+
# ---------------------------------------------------------------------
|
53
|
+
# Core Instruction Execution
|
54
|
+
# ---------------------------------------------------------------------
|
55
|
+
|
56
|
+
|
27
57
|
async def run_instruct(
|
28
58
|
ins: Instruct,
|
29
59
|
session: Session,
|
@@ -32,53 +62,50 @@ async def run_instruct(
|
|
32
62
|
verbose: bool = True,
|
33
63
|
**kwargs: Any,
|
34
64
|
) -> Any:
|
35
|
-
"""
|
36
|
-
|
37
|
-
|
38
|
-
ins: The instruction model to run.
|
39
|
-
session: The current session.
|
40
|
-
branch: The branch to operate on.
|
41
|
-
auto_run: Whether to automatically run nested instructions.
|
42
|
-
verbose: Whether to enable verbose output.
|
43
|
-
**kwargs: Additional keyword arguments.
|
44
|
-
|
45
|
-
Returns:
|
46
|
-
The result of the instruction execution.
|
65
|
+
"""
|
66
|
+
Execute a single instruction within a brainstorming session.
|
67
|
+
Optionally auto-run any child instructions that result.
|
47
68
|
"""
|
48
69
|
|
49
|
-
async def
|
70
|
+
async def _run_child_instruction(child_ins: Instruct):
|
71
|
+
"""
|
72
|
+
Helper for recursively running child instructions.
|
73
|
+
"""
|
50
74
|
if verbose:
|
51
|
-
|
52
|
-
|
53
|
-
if len(
|
54
|
-
else
|
75
|
+
snippet = (
|
76
|
+
child_ins.guidance[:100] + "..."
|
77
|
+
if len(child_ins.guidance) > 100
|
78
|
+
else child_ins.guidance
|
55
79
|
)
|
56
|
-
print(f"\n-----Running instruction-----\n{
|
57
|
-
|
80
|
+
print(f"\n-----Running instruction-----\n{snippet}")
|
81
|
+
child_branch = session.split(branch)
|
58
82
|
return await run_instruct(
|
59
|
-
|
83
|
+
child_ins, session, child_branch, False, verbose=verbose, **kwargs
|
60
84
|
)
|
61
85
|
|
86
|
+
# Prepare config for the branch operation
|
62
87
|
config = {**ins.model_dump(), **kwargs}
|
63
|
-
|
88
|
+
result = await branch.operate(**config)
|
64
89
|
branch.msgs.logger.dump()
|
65
|
-
instructs = []
|
66
|
-
|
67
|
-
if hasattr(res, "instruct_models"):
|
68
|
-
instructs = res.instruct_models
|
69
90
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
91
|
+
# Extract any newly generated instructions
|
92
|
+
instructs = []
|
93
|
+
if hasattr(result, "instruct_models"):
|
94
|
+
instructs = result.instruct_models
|
95
|
+
|
96
|
+
# If we're allowed to auto-run child instructions, handle them
|
97
|
+
if auto_run and instructs:
|
98
|
+
child_results = await alcall(instructs, _run_child_instruction)
|
99
|
+
combined = []
|
100
|
+
for c in child_results:
|
101
|
+
if isinstance(c, list):
|
102
|
+
combined.extend(c)
|
76
103
|
else:
|
77
|
-
|
78
|
-
|
79
|
-
return
|
104
|
+
combined.append(c)
|
105
|
+
combined.insert(0, result)
|
106
|
+
return combined
|
80
107
|
|
81
|
-
return
|
108
|
+
return result
|
82
109
|
|
83
110
|
|
84
111
|
async def brainstorm(
|
@@ -89,116 +116,314 @@ async def brainstorm(
|
|
89
116
|
auto_run: bool = True,
|
90
117
|
auto_explore: bool = False,
|
91
118
|
explore_kwargs: dict[str, Any] | None = None,
|
119
|
+
explore_strategy: Literal[
|
120
|
+
"concurrent",
|
121
|
+
"sequential",
|
122
|
+
"sequential_concurrent_chunk",
|
123
|
+
"concurrent_sequential_chunk",
|
124
|
+
] = "concurrent",
|
92
125
|
branch_kwargs: dict[str, Any] | None = None,
|
93
126
|
return_session: bool = False,
|
94
127
|
verbose: bool = False,
|
128
|
+
branch_as_default: bool = True,
|
95
129
|
**kwargs: Any,
|
96
130
|
) -> Any:
|
97
|
-
"""Perform a brainstorming session.
|
98
|
-
|
99
|
-
Args:
|
100
|
-
instruct: Instruction model or dictionary.
|
101
|
-
num_instruct: Number of instructions to generate.
|
102
|
-
session: Existing session or None to create a new one.
|
103
|
-
branch: Existing branch or reference.
|
104
|
-
auto_run: If True, automatically run generated instructions.
|
105
|
-
branch_kwargs: Additional arguments for branch creation.
|
106
|
-
return_session: If True, return the session with results.
|
107
|
-
verbose: Whether to enable verbose output.
|
108
|
-
**kwargs: Additional keyword arguments.
|
109
|
-
|
110
|
-
Returns:
|
111
|
-
The results of the brainstorming session, optionally with the session.
|
112
131
|
"""
|
132
|
+
High-level function to perform a brainstorming session.
|
113
133
|
|
134
|
+
Steps:
|
135
|
+
1. Run the initial 'instruct' prompt to generate suggestions.
|
136
|
+
2. Optionally auto-run those suggestions (auto_run=True).
|
137
|
+
3. Optionally explore the resulting instructions (auto_explore=True)
|
138
|
+
using the chosen strategy (concurrent, sequential, etc.).
|
139
|
+
"""
|
140
|
+
|
141
|
+
# -----------------------------------------------------------------
|
142
|
+
# Basic Validations and Setup
|
143
|
+
# -----------------------------------------------------------------
|
114
144
|
if auto_explore and not auto_run:
|
115
145
|
raise ValueError("auto_explore requires auto_run to be True.")
|
116
146
|
|
117
147
|
if verbose:
|
118
|
-
print(
|
148
|
+
print("Starting brainstorming...")
|
119
149
|
|
150
|
+
# Make sure the correct field model is present
|
120
151
|
field_models: list = kwargs.get("field_models", [])
|
121
152
|
if INSTRUCT_FIELD_MODEL not in field_models:
|
122
153
|
field_models.append(INSTRUCT_FIELD_MODEL)
|
123
|
-
|
124
154
|
kwargs["field_models"] = field_models
|
155
|
+
|
156
|
+
# Prepare session, branch, and the instruction
|
125
157
|
session, branch = prepare_session(session, branch, branch_kwargs)
|
126
|
-
|
127
|
-
|
128
|
-
|
158
|
+
prompt_str = PROMPT.format(num_instruct=num_instruct)
|
159
|
+
instruct = prepare_instruct(instruct, prompt_str)
|
160
|
+
|
161
|
+
# -----------------------------------------------------------------
|
162
|
+
# 1. Initial Brainstorm
|
163
|
+
# -----------------------------------------------------------------
|
129
164
|
res1 = await branch.operate(**instruct, **kwargs)
|
130
165
|
out = BrainstormOperation(initial=res1)
|
131
166
|
|
132
167
|
if verbose:
|
133
168
|
print("Initial brainstorming complete.")
|
134
169
|
|
135
|
-
|
136
|
-
|
137
|
-
async def run(ins_):
|
170
|
+
# Helper to run single instructions from the 'brainstorm'
|
171
|
+
async def run_brainstorm_instruction(ins_):
|
138
172
|
if verbose:
|
139
|
-
|
173
|
+
snippet = (
|
140
174
|
ins_.guidance[:100] + "..."
|
141
175
|
if len(ins_.guidance) > 100
|
142
176
|
else ins_.guidance
|
143
177
|
)
|
144
|
-
print(f"\n-----Running instruction-----\n{
|
145
|
-
|
178
|
+
print(f"\n-----Running instruction-----\n{snippet}")
|
179
|
+
new_branch = session.split(branch)
|
146
180
|
return await run_instruct(
|
147
|
-
ins_, session,
|
181
|
+
ins_, session, new_branch, auto_run, verbose=verbose, **kwargs
|
148
182
|
)
|
149
183
|
|
184
|
+
# -----------------------------------------------------------------
|
185
|
+
# 2. Auto-run child instructions if requested
|
186
|
+
# -----------------------------------------------------------------
|
150
187
|
if not auto_run:
|
151
188
|
if return_session:
|
152
189
|
return out, session
|
153
190
|
return out
|
154
191
|
|
192
|
+
# We run inside the context manager for branching
|
155
193
|
async with session.branches:
|
156
194
|
response_ = []
|
195
|
+
|
196
|
+
# If the initial result has instructions, run them
|
157
197
|
if hasattr(res1, "instruct_models"):
|
158
198
|
instructs: list[Instruct] = res1.instruct_models
|
159
|
-
|
160
|
-
|
199
|
+
brainstorm_results = await alcall(
|
200
|
+
instructs, run_brainstorm_instruction
|
201
|
+
)
|
202
|
+
brainstorm_results = to_flat_list(brainstorm_results, dropna=True)
|
161
203
|
|
162
|
-
|
163
|
-
|
164
|
-
|
204
|
+
# Filter out plain str/dict responses, keep model-based
|
205
|
+
filtered = [
|
206
|
+
r if not isinstance(r, (str, dict)) else None
|
207
|
+
for r in brainstorm_results
|
165
208
|
]
|
166
|
-
|
209
|
+
filtered = to_flat_list(filtered, unique=True, dropna=True)
|
210
|
+
|
167
211
|
out.brainstorm = (
|
168
|
-
|
212
|
+
filtered if isinstance(filtered, list) else [filtered]
|
169
213
|
)
|
170
|
-
|
214
|
+
# Insert the initial result at index 0 for reference
|
215
|
+
filtered.insert(0, res1)
|
216
|
+
response_ = filtered
|
171
217
|
|
218
|
+
# -----------------------------------------------------------------
|
219
|
+
# 3. Explore the results (if auto_explore = True)
|
220
|
+
# -----------------------------------------------------------------
|
172
221
|
if response_ and auto_explore:
|
173
|
-
|
174
|
-
|
175
|
-
if verbose:
|
176
|
-
msg_ = (
|
177
|
-
ins_.guidance[:100] + "..."
|
178
|
-
if len(ins_.guidance) > 100
|
179
|
-
else ins_.guidance
|
180
|
-
)
|
181
|
-
print(f"\n-----Exploring Idea-----\n{msg_}")
|
182
|
-
b_ = session.split(branch)
|
183
|
-
res = await b_.instruct(ins_, **(explore_kwargs or {}))
|
184
|
-
return InstructResponse(
|
185
|
-
instruct=ins_,
|
186
|
-
response=res,
|
187
|
-
)
|
188
|
-
|
189
|
-
response_ = to_flat_list(
|
222
|
+
# Gather all newly generated instructions
|
223
|
+
all_explore_instructs = to_flat_list(
|
190
224
|
[
|
191
|
-
|
192
|
-
for
|
193
|
-
if hasattr(
|
225
|
+
r.instruct_models
|
226
|
+
for r in response_
|
227
|
+
if hasattr(r, "instruct_models")
|
194
228
|
],
|
195
229
|
dropna=True,
|
196
230
|
unique=True,
|
197
231
|
)
|
198
|
-
res_explore = await alcall(response_, explore)
|
199
|
-
out.explore = res_explore
|
200
232
|
|
233
|
+
# Decide how to explore based on the strategy
|
234
|
+
match explore_strategy:
|
235
|
+
# ---------------------------------------------------------
|
236
|
+
# Strategy A: CONCURRENT
|
237
|
+
# ---------------------------------------------------------
|
238
|
+
case "concurrent":
|
239
|
+
|
240
|
+
async def explore_concurrently(ins_: Instruct):
|
241
|
+
if verbose:
|
242
|
+
snippet = (
|
243
|
+
ins_.guidance[:100] + "..."
|
244
|
+
if len(ins_.guidance) > 100
|
245
|
+
else ins_.guidance
|
246
|
+
)
|
247
|
+
print(f"\n-----Exploring Idea-----\n{snippet}")
|
248
|
+
new_branch = session.split(branch)
|
249
|
+
resp = await new_branch.instruct(
|
250
|
+
ins_, **(explore_kwargs or {})
|
251
|
+
)
|
252
|
+
return InstructResponse(instruct=ins_, response=resp)
|
253
|
+
|
254
|
+
res_explore = await alcall(
|
255
|
+
all_explore_instructs, explore_concurrently
|
256
|
+
)
|
257
|
+
out.explore = res_explore
|
258
|
+
|
259
|
+
# Add messages for logging / auditing
|
260
|
+
branch.msgs.add_message(
|
261
|
+
instruction="\n".join(
|
262
|
+
i.model_dump_json() for i in all_explore_instructs
|
263
|
+
)
|
264
|
+
)
|
265
|
+
branch.msgs.add_message(
|
266
|
+
assistant_response="\n".join(
|
267
|
+
i.model_dump_json() for i in res_explore
|
268
|
+
)
|
269
|
+
)
|
270
|
+
|
271
|
+
# ---------------------------------------------------------
|
272
|
+
# Strategy B: SEQUENTIAL
|
273
|
+
# ---------------------------------------------------------
|
274
|
+
case "sequential":
|
275
|
+
explore_results = []
|
276
|
+
|
277
|
+
# Warn/log if a large number of instructions
|
278
|
+
if len(all_explore_instructs) > 30:
|
279
|
+
all_explore_instructs = all_explore_instructs[:30]
|
280
|
+
logging.warning(
|
281
|
+
"Maximum number of instructions for sequential exploration is 50. defaulting to 50."
|
282
|
+
)
|
283
|
+
if len(all_explore_instructs) > 10:
|
284
|
+
logging.warning(
|
285
|
+
"Large number of instructions for sequential exploration. This may take a while."
|
286
|
+
)
|
287
|
+
|
288
|
+
for i in all_explore_instructs:
|
289
|
+
if verbose:
|
290
|
+
snippet = (
|
291
|
+
i.guidance[:100] + "..."
|
292
|
+
if len(i.guidance) > 100
|
293
|
+
else i.guidance
|
294
|
+
)
|
295
|
+
print(f"\n-----Exploring Idea-----\n{snippet}")
|
296
|
+
seq_res = await branch.instruct(
|
297
|
+
i, **(explore_kwargs or {})
|
298
|
+
)
|
299
|
+
explore_results.append(
|
300
|
+
InstructResponse(instruct=i, response=seq_res)
|
301
|
+
)
|
302
|
+
|
303
|
+
out.explore = explore_results
|
304
|
+
|
305
|
+
# ---------------------------------------------------------
|
306
|
+
# Strategy C: SEQUENTIAL_CONCURRENT_CHUNK
|
307
|
+
# (chunks processed sequentially, each chunk in parallel)
|
308
|
+
# ---------------------------------------------------------
|
309
|
+
case "sequential_concurrent_chunk":
|
310
|
+
chunk_size = (explore_kwargs or {}).get("chunk_size", 5)
|
311
|
+
all_responses = []
|
312
|
+
|
313
|
+
async def explore_concurrent_chunk(
|
314
|
+
sub_instructs: list[Instruct], base_branch: Branch
|
315
|
+
):
|
316
|
+
"""
|
317
|
+
Explore instructions in a single chunk concurrently.
|
318
|
+
"""
|
319
|
+
if verbose:
|
320
|
+
print(
|
321
|
+
f"\n--- Exploring a chunk of size {len(sub_instructs)} ---\n"
|
322
|
+
)
|
323
|
+
|
324
|
+
async def _explore(ins_: Instruct):
|
325
|
+
child_branch = session.split(base_branch)
|
326
|
+
child_resp = await child_branch.instruct(
|
327
|
+
ins_, **(explore_kwargs or {})
|
328
|
+
)
|
329
|
+
return InstructResponse(
|
330
|
+
instruct=ins_, response=child_resp
|
331
|
+
)
|
332
|
+
|
333
|
+
# Run all instructions in the chunk concurrently
|
334
|
+
res_chunk = await alcall(sub_instructs, _explore)
|
335
|
+
|
336
|
+
# Log messages for debugging / auditing
|
337
|
+
next_branch = session.split(base_branch)
|
338
|
+
next_branch.msgs.add_message(
|
339
|
+
instruction="\n".join(
|
340
|
+
i.model_dump_json() for i in sub_instructs
|
341
|
+
)
|
342
|
+
)
|
343
|
+
next_branch.msgs.add_message(
|
344
|
+
assistant_response="\n".join(
|
345
|
+
i.model_dump_json() for i in res_chunk
|
346
|
+
)
|
347
|
+
)
|
348
|
+
return res_chunk, next_branch
|
349
|
+
|
350
|
+
# Process each chunk sequentially
|
351
|
+
for chunk in chunked(all_explore_instructs, chunk_size):
|
352
|
+
chunk_result, branch = await explore_concurrent_chunk(
|
353
|
+
chunk, branch
|
354
|
+
)
|
355
|
+
all_responses.extend(chunk_result)
|
356
|
+
|
357
|
+
out.explore = all_responses
|
358
|
+
|
359
|
+
# ---------------------------------------------------------
|
360
|
+
# Strategy D: CONCURRENT_SEQUENTIAL_CHUNK
|
361
|
+
# (all chunks processed concurrently, each chunk sequentially)
|
362
|
+
# ---------------------------------------------------------
|
363
|
+
case "concurrent_sequential_chunk":
|
364
|
+
chunk_size = (explore_kwargs or {}).get("chunk_size", 5)
|
365
|
+
all_chunks = list(
|
366
|
+
chunked(all_explore_instructs, chunk_size)
|
367
|
+
)
|
368
|
+
|
369
|
+
async def explore_chunk_sequentially(
|
370
|
+
sub_instructs: list[Instruct],
|
371
|
+
):
|
372
|
+
"""
|
373
|
+
Explore instructions in a single chunk, one at a time.
|
374
|
+
"""
|
375
|
+
chunk_results = []
|
376
|
+
local_branch = session.split(branch)
|
377
|
+
|
378
|
+
for ins_ in sub_instructs:
|
379
|
+
if verbose:
|
380
|
+
snippet = (
|
381
|
+
ins_.guidance[:100] + "..."
|
382
|
+
if len(ins_.guidance) > 100
|
383
|
+
else ins_.guidance
|
384
|
+
)
|
385
|
+
print(
|
386
|
+
f"\n-----Exploring Idea (sequential in chunk)-----\n{snippet}"
|
387
|
+
)
|
388
|
+
|
389
|
+
seq_resp = await local_branch.instruct(
|
390
|
+
ins_, **(explore_kwargs or {})
|
391
|
+
)
|
392
|
+
chunk_results.append(
|
393
|
+
InstructResponse(
|
394
|
+
instruct=ins_, response=seq_resp
|
395
|
+
)
|
396
|
+
)
|
397
|
+
|
398
|
+
return chunk_results
|
399
|
+
|
400
|
+
# Run all chunks in parallel
|
401
|
+
all_responses = await alcall(
|
402
|
+
all_chunks,
|
403
|
+
explore_chunk_sequentially,
|
404
|
+
flatten=True,
|
405
|
+
dropna=True,
|
406
|
+
)
|
407
|
+
out.explore = all_responses
|
408
|
+
|
409
|
+
# Log final messages
|
410
|
+
branch.msgs.add_message(
|
411
|
+
instruction="\n".join(
|
412
|
+
i.model_dump_json() for i in all_explore_instructs
|
413
|
+
)
|
414
|
+
)
|
415
|
+
branch.msgs.add_message(
|
416
|
+
assistant_response="\n".join(
|
417
|
+
i.model_dump_json() for i in all_responses
|
418
|
+
)
|
419
|
+
)
|
420
|
+
|
421
|
+
if branch_as_default:
|
422
|
+
session.change_default_branch(branch)
|
423
|
+
|
424
|
+
# -----------------------------------------------------------------
|
425
|
+
# 4. Return Results
|
426
|
+
# -----------------------------------------------------------------
|
201
427
|
if return_session:
|
202
428
|
return out, session
|
203
|
-
|
204
429
|
return out
|
lionagi/operations/plan/plan.py
CHANGED
@@ -2,10 +2,11 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
|
-
|
6
5
|
from lionagi.core.session.branch import Branch
|
7
6
|
from lionagi.core.session.session import Session
|
8
7
|
from lionagi.core.typing import ID, Any, BaseModel, Literal
|
8
|
+
from lionagi.libs.func.types import alcall
|
9
|
+
from lionagi.libs.parse import to_flat_list
|
9
10
|
from lionagi.protocols.operatives.instruct import (
|
10
11
|
INSTRUCT_FIELD_MODEL,
|
11
12
|
Instruct,
|
@@ -15,13 +16,45 @@ from lionagi.protocols.operatives.instruct import (
|
|
15
16
|
from ..utils import prepare_instruct, prepare_session
|
16
17
|
from .prompt import EXPANSION_PROMPT, PLAN_PROMPT
|
17
18
|
|
19
|
+
# ---------------------------------------------------------------------
|
20
|
+
# Data Model
|
21
|
+
# ---------------------------------------------------------------------
|
22
|
+
|
18
23
|
|
19
24
|
class PlanOperation(BaseModel):
|
25
|
+
"""
|
26
|
+
Stores all relevant outcomes for a multi-step Plan:
|
27
|
+
* initial: The result of the initial plan prompt
|
28
|
+
* plan: A list of plan steps (Instruct objects) generated from the initial planning
|
29
|
+
* execute: Any responses from executing those plan steps
|
30
|
+
"""
|
31
|
+
|
20
32
|
initial: Any
|
21
33
|
plan: list[Instruct] | None = None
|
22
34
|
execute: list[InstructResponse] | None = None
|
23
35
|
|
24
36
|
|
37
|
+
# ---------------------------------------------------------------------
|
38
|
+
# Utilities
|
39
|
+
# ---------------------------------------------------------------------
|
40
|
+
|
41
|
+
|
42
|
+
def chunked(iterable, n):
|
43
|
+
"""
|
44
|
+
Yield successive n-sized chunks from an iterable.
|
45
|
+
Example:
|
46
|
+
>>> list(chunked([1,2,3,4,5], 2))
|
47
|
+
[[1,2],[3,4],[5]]
|
48
|
+
"""
|
49
|
+
for i in range(0, len(iterable), n):
|
50
|
+
yield iterable[i : i + n]
|
51
|
+
|
52
|
+
|
53
|
+
# ---------------------------------------------------------------------
|
54
|
+
# Single-Step Runner
|
55
|
+
# ---------------------------------------------------------------------
|
56
|
+
|
57
|
+
|
25
58
|
async def run_step(
|
26
59
|
ins: Instruct,
|
27
60
|
session: Session,
|
@@ -29,33 +62,41 @@ async def run_step(
|
|
29
62
|
verbose: bool = True,
|
30
63
|
**kwargs: Any,
|
31
64
|
) -> Any:
|
32
|
-
"""
|
65
|
+
"""
|
66
|
+
Execute a single step of the plan with an 'expansion' or guidance prompt.
|
33
67
|
|
34
68
|
Args:
|
35
69
|
ins: The instruction model for the step.
|
36
|
-
session: The current session.
|
37
|
-
branch: The branch to operate on.
|
70
|
+
session: The current session context.
|
71
|
+
branch: The branch to operate on for this step.
|
38
72
|
verbose: Whether to enable verbose output.
|
39
|
-
**kwargs: Additional keyword arguments.
|
73
|
+
**kwargs: Additional keyword arguments passed to the branch operation.
|
40
74
|
|
41
75
|
Returns:
|
42
|
-
The result of the branch operation.
|
76
|
+
The result of the branch operation (which may contain more instructions).
|
43
77
|
"""
|
44
78
|
if verbose:
|
45
|
-
|
79
|
+
snippet = (
|
46
80
|
ins.instruction[:100] + "..."
|
47
81
|
if len(ins.instruction) > 100
|
48
82
|
else ins.instruction
|
49
83
|
)
|
50
|
-
print(f"Further planning: {
|
84
|
+
print(f"Further planning: {snippet}")
|
51
85
|
|
86
|
+
# Incorporate the EXPANSION_PROMPT into guidance
|
52
87
|
config = {**ins.model_dump(), **kwargs}
|
53
|
-
|
54
|
-
config["guidance"] = EXPANSION_PROMPT
|
88
|
+
guidance_text = config.pop("guidance", "")
|
89
|
+
config["guidance"] = f"{EXPANSION_PROMPT}\n{guidance_text}"
|
90
|
+
|
91
|
+
# Run the step
|
92
|
+
result = await branch.operate(**config)
|
93
|
+
branch.msgs.logger.dump() # Dump logs if needed
|
94
|
+
return result
|
55
95
|
|
56
|
-
|
57
|
-
|
58
|
-
|
96
|
+
|
97
|
+
# ---------------------------------------------------------------------
|
98
|
+
# Main Plan Function (with Multiple Execution Strategies)
|
99
|
+
# ---------------------------------------------------------------------
|
59
100
|
|
60
101
|
|
61
102
|
async def plan(
|
@@ -65,108 +106,280 @@ async def plan(
|
|
65
106
|
branch: Branch | ID.Ref | None = None,
|
66
107
|
auto_run: bool = True,
|
67
108
|
auto_execute: bool = False,
|
68
|
-
execution_strategy: Literal[
|
109
|
+
execution_strategy: Literal[
|
110
|
+
"sequential",
|
111
|
+
"concurrent",
|
112
|
+
"sequential_concurrent_chunk",
|
113
|
+
"concurrent_sequential_chunk",
|
114
|
+
] = "sequential",
|
69
115
|
execution_kwargs: dict[str, Any] | None = None,
|
70
116
|
branch_kwargs: dict[str, Any] | None = None,
|
71
117
|
return_session: bool = False,
|
72
118
|
verbose: bool = True,
|
73
119
|
**kwargs: Any,
|
74
|
-
) -> PlanOperation | tuple[
|
75
|
-
"""
|
120
|
+
) -> PlanOperation | tuple[PlanOperation, Session]:
|
121
|
+
"""
|
122
|
+
Create and optionally execute a multi-step plan with up to `num_steps`.
|
123
|
+
|
124
|
+
Steps:
|
125
|
+
1. Generate an initial plan with up to `num_steps`.
|
126
|
+
2. Optionally (auto_run=True) expand on each planned step
|
127
|
+
to refine or further clarify them.
|
128
|
+
3. Optionally (auto_execute=True) execute those refined steps
|
129
|
+
according to `execution_strategy`.
|
76
130
|
|
77
131
|
Args:
|
78
|
-
instruct:
|
79
|
-
num_steps:
|
80
|
-
session:
|
81
|
-
branch:
|
82
|
-
auto_run: If True, automatically run the steps.
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
132
|
+
instruct: Initial instruction or a dict describing it.
|
133
|
+
num_steps: Maximum number of plan steps (must be <= 5).
|
134
|
+
session: An existing Session, or None to create a new one.
|
135
|
+
branch: An existing Branch, or None to create a new one.
|
136
|
+
auto_run: If True, automatically run the intermediate plan steps.
|
137
|
+
auto_execute: If True, automatically execute the fully refined steps.
|
138
|
+
execution_strategy:
|
139
|
+
- "sequential" (default) runs steps one by one
|
140
|
+
- "concurrent" runs all steps in parallel
|
141
|
+
- "sequential_concurrent_chunk" processes chunks sequentially, each chunk in parallel
|
142
|
+
- "concurrent_sequential_chunk" processes all chunks in parallel, each chunk sequentially
|
143
|
+
execution_kwargs: Extra kwargs used during execution calls.
|
144
|
+
branch_kwargs: Extra kwargs for branch/session creation.
|
145
|
+
return_session: Whether to return (PlanOperation, Session) instead of just PlanOperation.
|
146
|
+
verbose: If True, prints verbose logs.
|
147
|
+
**kwargs: Additional arguments for the initial plan operation.
|
87
148
|
|
88
149
|
Returns:
|
89
|
-
|
150
|
+
A PlanOperation object containing:
|
151
|
+
- initial plan
|
152
|
+
- (optional) plan expansions
|
153
|
+
- (optional) execution responses
|
154
|
+
Optionally returns the session as well, if `return_session=True`.
|
90
155
|
"""
|
156
|
+
|
157
|
+
# -----------------------------------------------------------------
|
158
|
+
# 0. Basic Validation & Setup
|
159
|
+
# -----------------------------------------------------------------
|
91
160
|
if num_steps > 5:
|
92
161
|
raise ValueError("Number of steps must be 5 or less")
|
93
162
|
|
94
163
|
if verbose:
|
95
164
|
print(f"Planning execution with {num_steps} steps...")
|
96
165
|
|
166
|
+
# Ensure the correct field model
|
97
167
|
field_models: list = kwargs.get("field_models", [])
|
98
168
|
if INSTRUCT_FIELD_MODEL not in field_models:
|
99
169
|
field_models.append(INSTRUCT_FIELD_MODEL)
|
100
170
|
kwargs["field_models"] = field_models
|
171
|
+
|
172
|
+
# Prepare session/branch
|
101
173
|
session, branch = prepare_session(session, branch, branch_kwargs)
|
102
|
-
execute_branch: Branch = session.split(
|
103
|
-
|
104
|
-
|
105
|
-
)
|
174
|
+
execute_branch: Branch = session.split(
|
175
|
+
branch
|
176
|
+
) # a separate branch for execution
|
106
177
|
|
107
|
-
|
108
|
-
|
178
|
+
# -----------------------------------------------------------------
|
179
|
+
# 1. Run the Initial Plan Prompt
|
180
|
+
# -----------------------------------------------------------------
|
181
|
+
plan_prompt = PLAN_PROMPT.format(num_steps=num_steps)
|
182
|
+
instruct = prepare_instruct(instruct, plan_prompt)
|
183
|
+
initial_res = await branch.operate(**instruct, **kwargs)
|
184
|
+
|
185
|
+
# Wrap initial result in the PlanOperation
|
186
|
+
out = PlanOperation(initial=initial_res)
|
109
187
|
|
110
188
|
if verbose:
|
111
189
|
print("Initial planning complete. Starting step planning...")
|
112
190
|
|
191
|
+
# If we aren't auto-running the steps, just return the initial plan
|
113
192
|
if not auto_run:
|
114
|
-
if return_session
|
115
|
-
return res1, session
|
116
|
-
return res1
|
193
|
+
return (out, session) if return_session else out
|
117
194
|
|
195
|
+
# -----------------------------------------------------------------
|
196
|
+
# 2. Expand Each Step (auto_run=True)
|
197
|
+
# -----------------------------------------------------------------
|
118
198
|
results = []
|
119
|
-
if hasattr(
|
120
|
-
instructs: list[Instruct] =
|
121
|
-
for i,
|
199
|
+
if hasattr(initial_res, "instruct_models"):
|
200
|
+
instructs: list[Instruct] = initial_res.instruct_models
|
201
|
+
for i, step_ins in enumerate(instructs, start=1):
|
122
202
|
if verbose:
|
123
203
|
print(f"\n----- Planning step {i}/{len(instructs)} -----")
|
124
|
-
|
125
|
-
|
204
|
+
expanded_res = await run_step(
|
205
|
+
step_ins, session, branch, verbose=verbose, **kwargs
|
126
206
|
)
|
127
|
-
results.append(
|
207
|
+
results.append(expanded_res)
|
128
208
|
|
129
209
|
if verbose:
|
130
|
-
print("\nAll planning
|
210
|
+
print("\nAll planning steps expanded/refined successfully!")
|
211
|
+
|
212
|
+
# Gather all newly created plan instructions
|
213
|
+
refined_plans = []
|
214
|
+
for step_result in results:
|
215
|
+
if hasattr(step_result, "instruct_models"):
|
216
|
+
for model in step_result.instruct_models:
|
217
|
+
if model and model not in refined_plans:
|
218
|
+
refined_plans.append(model)
|
131
219
|
|
132
|
-
|
133
|
-
for res in results:
|
134
|
-
if hasattr(res, "instruct_models"):
|
135
|
-
for i in res.instruct_models:
|
136
|
-
if i and i not in all_plans:
|
137
|
-
all_plans.append(i)
|
138
|
-
out.plan = all_plans
|
220
|
+
out.plan = refined_plans
|
139
221
|
|
222
|
+
# -----------------------------------------------------------------
|
223
|
+
# 3. Execute the Plan Steps (auto_execute=True)
|
224
|
+
# -----------------------------------------------------------------
|
140
225
|
if auto_execute:
|
141
226
|
if verbose:
|
142
|
-
print("\nStarting execution of all steps...")
|
143
|
-
|
227
|
+
print("\nStarting execution of all plan steps...")
|
228
|
+
|
229
|
+
# We now handle multiple strategies:
|
144
230
|
match execution_strategy:
|
231
|
+
|
232
|
+
# ---------------------------------------------------------
|
233
|
+
# Strategy A: SEQUENTIAL
|
234
|
+
# ---------------------------------------------------------
|
145
235
|
case "sequential":
|
146
|
-
|
236
|
+
seq_results = []
|
237
|
+
for i, plan_step in enumerate(refined_plans, start=1):
|
238
|
+
if verbose:
|
239
|
+
snippet = (
|
240
|
+
plan_step.instruction[:100] + "..."
|
241
|
+
if len(plan_step.instruction) > 100
|
242
|
+
else plan_step.instruction
|
243
|
+
)
|
244
|
+
print(
|
245
|
+
f"\n------ Executing step {i}/{len(refined_plans)} ------"
|
246
|
+
)
|
247
|
+
print(f"Instruction: {snippet}")
|
248
|
+
|
249
|
+
step_response = await execute_branch.instruct(
|
250
|
+
plan_step, **(execution_kwargs or {})
|
251
|
+
)
|
252
|
+
seq_results.append(
|
253
|
+
InstructResponse(
|
254
|
+
instruct=plan_step, response=step_response
|
255
|
+
)
|
256
|
+
)
|
257
|
+
|
258
|
+
out.execute = seq_results
|
259
|
+
if verbose:
|
260
|
+
print("\nAll steps executed successfully (sequential)!")
|
261
|
+
|
262
|
+
# ---------------------------------------------------------
|
263
|
+
# Strategy B: CONCURRENT
|
264
|
+
# ---------------------------------------------------------
|
265
|
+
case "concurrent":
|
266
|
+
|
267
|
+
async def execute_step_concurrently(plan_step: Instruct):
|
268
|
+
if verbose:
|
269
|
+
snippet = (
|
270
|
+
plan_step.instruction[:100] + "..."
|
271
|
+
if len(plan_step.instruction) > 100
|
272
|
+
else plan_step.instruction
|
273
|
+
)
|
274
|
+
print(f"\n------ Executing step (concurrently) ------")
|
275
|
+
print(f"Instruction: {snippet}")
|
276
|
+
local_branch = session.split(execute_branch)
|
277
|
+
resp = await local_branch.instruct(
|
278
|
+
plan_step, **(execution_kwargs or {})
|
279
|
+
)
|
280
|
+
return InstructResponse(instruct=plan_step, response=resp)
|
281
|
+
|
282
|
+
# Launch all steps in parallel
|
283
|
+
concurrent_res = await alcall(
|
284
|
+
refined_plans, execute_step_concurrently
|
285
|
+
)
|
286
|
+
out.execute = concurrent_res
|
287
|
+
if verbose:
|
288
|
+
print("\nAll steps executed successfully (concurrent)!")
|
289
|
+
|
290
|
+
# ---------------------------------------------------------
|
291
|
+
# Strategy C: SEQUENTIAL_CONCURRENT_CHUNK
|
292
|
+
# - process plan steps in chunks (one chunk after another),
|
293
|
+
# - each chunk’s steps run in parallel.
|
294
|
+
# ---------------------------------------------------------
|
295
|
+
case "sequential_concurrent_chunk":
|
296
|
+
chunk_size = (execution_kwargs or {}).get("chunk_size", 5)
|
297
|
+
all_exec_responses = []
|
298
|
+
|
299
|
+
async def execute_chunk_concurrently(
|
300
|
+
sub_steps: list[Instruct],
|
301
|
+
):
|
147
302
|
if verbose:
|
148
303
|
print(
|
149
|
-
f"\n
|
304
|
+
f"\n--- Executing a chunk of size {len(sub_steps)} concurrently ---"
|
150
305
|
)
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
306
|
+
|
307
|
+
async def _execute(plan_step: Instruct):
|
308
|
+
local_branch = session.split(execute_branch)
|
309
|
+
resp = await local_branch.instruct(
|
310
|
+
plan_step, **(execution_kwargs or {})
|
311
|
+
)
|
312
|
+
return InstructResponse(
|
313
|
+
instruct=plan_step, response=resp
|
155
314
|
)
|
156
|
-
|
157
|
-
|
158
|
-
|
315
|
+
|
316
|
+
# run each chunk in parallel
|
317
|
+
return await alcall(sub_steps, _execute)
|
318
|
+
|
319
|
+
# process each chunk sequentially
|
320
|
+
for chunk in chunked(refined_plans, chunk_size):
|
321
|
+
chunk_responses = await execute_chunk_concurrently(chunk)
|
322
|
+
all_exec_responses.extend(chunk_responses)
|
323
|
+
|
324
|
+
out.execute = all_exec_responses
|
325
|
+
if verbose:
|
326
|
+
print(
|
327
|
+
"\nAll steps executed successfully (sequential concurrent chunk)!"
|
159
328
|
)
|
160
|
-
|
161
|
-
|
162
|
-
|
329
|
+
|
330
|
+
# ---------------------------------------------------------
|
331
|
+
# Strategy D: CONCURRENT_SEQUENTIAL_CHUNK
|
332
|
+
# - split plan steps into chunks,
|
333
|
+
# - run all chunks in parallel,
|
334
|
+
# - but each chunk’s steps run sequentially.
|
335
|
+
# ---------------------------------------------------------
|
336
|
+
case "concurrent_sequential_chunk":
|
337
|
+
chunk_size = (execution_kwargs or {}).get("chunk_size", 5)
|
338
|
+
all_chunks = list(chunked(refined_plans, chunk_size))
|
339
|
+
|
340
|
+
async def execute_chunk_sequentially(
|
341
|
+
sub_steps: list[Instruct],
|
342
|
+
):
|
343
|
+
chunk_result = []
|
344
|
+
local_branch = session.split(execute_branch)
|
345
|
+
for plan_step in sub_steps:
|
346
|
+
if verbose:
|
347
|
+
snippet = (
|
348
|
+
plan_step.instruction[:100] + "..."
|
349
|
+
if len(plan_step.instruction) > 100
|
350
|
+
else plan_step.instruction
|
351
|
+
)
|
352
|
+
print(
|
353
|
+
f"\n--- Executing step (sequential in chunk) ---\nInstruction: {snippet}"
|
354
|
+
)
|
355
|
+
resp = await local_branch.instruct(
|
356
|
+
plan_step, **(execution_kwargs or {})
|
357
|
+
)
|
358
|
+
chunk_result.append(
|
359
|
+
InstructResponse(instruct=plan_step, response=resp)
|
360
|
+
)
|
361
|
+
return chunk_result
|
362
|
+
|
363
|
+
# run all chunks in parallel, each chunk sequentially
|
364
|
+
parallel_chunk_results = await alcall(
|
365
|
+
all_chunks,
|
366
|
+
execute_chunk_sequentially,
|
367
|
+
flatten=True,
|
368
|
+
dropna=True,
|
369
|
+
)
|
370
|
+
|
371
|
+
out.execute = parallel_chunk_results
|
163
372
|
if verbose:
|
164
|
-
print(
|
373
|
+
print(
|
374
|
+
"\nAll steps executed successfully (concurrent sequential chunk)!"
|
375
|
+
)
|
376
|
+
|
165
377
|
case _:
|
166
378
|
raise ValueError(
|
167
379
|
f"Invalid execution strategy: {execution_strategy}"
|
168
380
|
)
|
169
381
|
|
170
|
-
|
171
|
-
|
172
|
-
|
382
|
+
# -----------------------------------------------------------------
|
383
|
+
# 4. Final Return
|
384
|
+
# -----------------------------------------------------------------
|
385
|
+
return (out, session) if return_session else out
|
lionagi/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "0.5.
|
1
|
+
__version__ = "0.5.4"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
lionagi/__init__.py,sha256=oybfu2VsZc4ElN7ZeaW3KQrz8T8EcSDHPA8lUE-8G2I,537
|
2
2
|
lionagi/settings.py,sha256=BOjxRV4N9zQJervvajPhbaHmgZ-nhbCy7AaQJi3Avug,2726
|
3
|
-
lionagi/version.py,sha256=
|
3
|
+
lionagi/version.py,sha256=DITpct-LrdIsTgwx2NgH5Ghx5y8Xgz1YMimy1ZV5RTY,22
|
4
4
|
lionagi/core/__init__.py,sha256=v8vNyJVIVj8_Oz9RJdVe6ZKUQMYTgDh1VQpnr1KdLaw,112
|
5
5
|
lionagi/core/_class_registry.py,sha256=srSWefqCS9EZrMvyA8zCrZ9KFvzAhTIj8g6mJG5KlIc,1982
|
6
6
|
lionagi/core/action/__init__.py,sha256=v8vNyJVIVj8_Oz9RJdVe6ZKUQMYTgDh1VQpnr1KdLaw,112
|
@@ -56,7 +56,7 @@ lionagi/core/models/types.py,sha256=elcUuz_9dx4AhZddnICF-Cs62VJWIBqMET7MiRe4c1I,
|
|
56
56
|
lionagi/core/session/__init__.py,sha256=v8vNyJVIVj8_Oz9RJdVe6ZKUQMYTgDh1VQpnr1KdLaw,112
|
57
57
|
lionagi/core/session/branch.py,sha256=r6yNXwTm0oYA-9YOereuvLJtDnhj9IJWJ5fjTyKN88U,4406
|
58
58
|
lionagi/core/session/branch_mixins.py,sha256=C9lGHmD1AmXAePw0kGIeuZjZ7SzOrFcIwV6rVaGhoGg,19623
|
59
|
-
lionagi/core/session/session.py,sha256=
|
59
|
+
lionagi/core/session/session.py,sha256=cutece_iTs5K_m5soRfU9oTfHmw1icDEvx77E1RelIM,5129
|
60
60
|
lionagi/core/session/types.py,sha256=MUGTSa2HWK79p7z-CG22RFP07N5AKnPVNXZwZt_wIvU,202
|
61
61
|
lionagi/core/typing/__init__.py,sha256=Y9BK1OUXzjQgIo3epCVwWqUYhFwQQ_ayhRwI1UOmINg,228
|
62
62
|
lionagi/core/typing/_concepts.py,sha256=uIzqfwtPBsIREhvT7NDAowc4i-u-69n_DRzLHzvHZO4,3730
|
@@ -257,7 +257,7 @@ lionagi/libs/func/throttle.py,sha256=iOOmS6i81NGRCClf4WaIhMMXwPt_rZ6WXYBqMJ_weEE
|
|
257
257
|
lionagi/libs/func/types.py,sha256=wdjGNmY82pVACQBuDMUt3XJO0G9_wKHR7VesOeMxo_A,831
|
258
258
|
lionagi/libs/func/utils.py,sha256=-LMdUEjksXP6JjjcUBh0XEQiXF30Zmv3xpKbmXjfya8,2674
|
259
259
|
lionagi/libs/func/async_calls/__init__.py,sha256=qDHIkH7B-Ka5NJqeeyu_YL3TY36xL8kBwTjtCR4H8AU,495
|
260
|
-
lionagi/libs/func/async_calls/alcall.py,sha256=
|
260
|
+
lionagi/libs/func/async_calls/alcall.py,sha256=GhPXId0YLvfxpDSYOABwr_3D-nRu8aLWshaYboJQzmQ,7436
|
261
261
|
lionagi/libs/func/async_calls/bcall.py,sha256=gwfKpRZkExjVn-1YGZfaboFES8RqUgyaBrdpNtz1IdY,4436
|
262
262
|
lionagi/libs/func/async_calls/mcall.py,sha256=9O5gWbBT4iIqXfcdZjgAdqsOSLWrNS4_tt6ou231ozA,4607
|
263
263
|
lionagi/libs/func/async_calls/pcall.py,sha256=6u3RJPV-3yOkWxC9iSoVFl1veFfZFJpR0QRyGtfBODI,5831
|
@@ -317,10 +317,10 @@ lionagi/libs/string_similarity/utils.py,sha256=NdD0qF5tuytWBsm0WMrH0gRBBSxw2p4-m
|
|
317
317
|
lionagi/operations/__init__.py,sha256=Dt7o6DFP7zVR-uxZ4xsGHQcse3XVlF6S8Y9NhaUTn_4,68
|
318
318
|
lionagi/operations/utils.py,sha256=kn5SkZRczl1aQ-vJBeVPlMdeyUUD0s5iyuAW4P6KOvQ,1164
|
319
319
|
lionagi/operations/brainstorm/__init__.py,sha256=amsoH65wepsx58DfgH-TRTN1wDH5TC24qYI_f02zkVg,61
|
320
|
-
lionagi/operations/brainstorm/brainstorm.py,sha256=
|
320
|
+
lionagi/operations/brainstorm/brainstorm.py,sha256=1Uuc11OH34jEYfDdombX5ui9b-bJTn4bVSLt0jjQUIc,16747
|
321
321
|
lionagi/operations/brainstorm/prompt.py,sha256=3a7LsmtiqGAK5mtWoX-2qhsjETBzBx8FxM3cFCBEoOo,497
|
322
322
|
lionagi/operations/plan/__init__.py,sha256=SVqoVmlSGz9lsLztm487H2qOLwgyFxSi2yZ8ubn-bgE,43
|
323
|
-
lionagi/operations/plan/plan.py,sha256=
|
323
|
+
lionagi/operations/plan/plan.py,sha256=AX4h_TeyhcXag572ywN9rmvo3fEiuGER7skAKf25_LY,15329
|
324
324
|
lionagi/operations/plan/prompt.py,sha256=sKHa_jDahzCJ60oILj1XNYCIlbS-H8ybKRXpf9zd5x0,880
|
325
325
|
lionagi/operations/select/__init__.py,sha256=dUd-KS1l404_ueYlIQsVNhS9jAqjn5pJbtUEbbh6KlI,49
|
326
326
|
lionagi/operations/select/prompt.py,sha256=wbmuDC96fcQ4LFKjqmeErOQwVRpGWRqcwUeLTWnbeNs,186
|
@@ -368,7 +368,7 @@ lionagi/strategies/sequential_chunk.py,sha256=jG_WZXG-Ra3yd30CmX4b3XeCNAUrZGA2-i
|
|
368
368
|
lionagi/strategies/sequential_concurrent_chunk.py,sha256=H7GShaqYlD5XxNJMG2GdOR4Vl8JHDhZb5jxNq8zY0hI,3365
|
369
369
|
lionagi/strategies/types.py,sha256=fEvE4d1H4SeCcXcd2dz3q4k8jFIBtxYzjxDN7eJRLtI,769
|
370
370
|
lionagi/strategies/utils.py,sha256=DX1dvxia8cNRqEJJbssJ3mgRzo7kgWCTA4y5DYLCCZE,1281
|
371
|
-
lionagi-0.5.
|
372
|
-
lionagi-0.5.
|
373
|
-
lionagi-0.5.
|
374
|
-
lionagi-0.5.
|
371
|
+
lionagi-0.5.4.dist-info/METADATA,sha256=or-K2I6vye-JTu559FMXpy14cZlI5_3xLAgLCURMu1w,22736
|
372
|
+
lionagi-0.5.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
373
|
+
lionagi-0.5.4.dist-info/licenses/LICENSE,sha256=VXFWsdoN5AAknBCgFqQNgPWYx7OPp-PFEP961zGdOjc,11288
|
374
|
+
lionagi-0.5.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|