lionagi 0.5.3__py3-none-any.whl → 0.5.4__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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
|