lionagi 0.5.3__py3-none-any.whl → 0.5.5__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/action/action_manager.py +2 -0
- lionagi/core/communication/assistant_response.py +10 -0
- lionagi/core/communication/message.py +1 -1
- lionagi/core/communication/message_manager.py +13 -0
- lionagi/core/communication/utils.py +4 -2
- lionagi/core/session/branch_mixins.py +76 -39
- lionagi/core/session/session.py +3 -3
- lionagi/integrations/anthropic_/AnthropicModel.py +4 -9
- lionagi/integrations/anthropic_/AnthropicService.py +10 -0
- lionagi/integrations/anthropic_/anthropic_max_output_token_data.yaml +5 -0
- lionagi/integrations/anthropic_/anthropic_price_data.yaml +26 -6
- lionagi/integrations/anthropic_/version.py +1 -1
- lionagi/integrations/groq_/GroqService.py +5 -0
- lionagi/integrations/groq_/version.py +1 -1
- lionagi/integrations/litellm_/imodel.py +5 -0
- lionagi/integrations/openai_/OpenAIModel.py +0 -4
- lionagi/integrations/openai_/OpenAIService.py +9 -0
- lionagi/integrations/openai_/version.py +1 -1
- lionagi/integrations/perplexity_/PerplexityService.py +5 -0
- lionagi/integrations/perplexity_/version.py +1 -1
- lionagi/libs/func/async_calls/alcall.py +7 -0
- lionagi/operations/brainstorm/brainstorm.py +318 -93
- lionagi/operations/plan/plan.py +280 -67
- lionagi/service/imodel.py +5 -0
- lionagi/version.py +1 -1
- {lionagi-0.5.3.dist-info → lionagi-0.5.5.dist-info}/METADATA +1 -1
- {lionagi-0.5.3.dist-info → lionagi-0.5.5.dist-info}/RECORD +29 -29
- {lionagi-0.5.3.dist-info → lionagi-0.5.5.dist-info}/WHEEL +0 -0
- {lionagi-0.5.3.dist-info → lionagi-0.5.5.dist-info}/licenses/LICENSE +0 -0
@@ -253,6 +253,8 @@ class ActionManager:
|
|
253
253
|
ValueError: If a specified tool is not registered.
|
254
254
|
TypeError: If an unsupported tool type is provided.
|
255
255
|
"""
|
256
|
+
if isinstance(tools, list | tuple) and len(tools) == 1:
|
257
|
+
tools = tools[0]
|
256
258
|
if isinstance(tools, bool):
|
257
259
|
if tools:
|
258
260
|
tool_kwarg = {"tools": self.schema_list}
|
@@ -146,6 +146,16 @@ class AssistantResponse(RoledMessage):
|
|
146
146
|
"""
|
147
147
|
return copy(self.content["assistant_response"])
|
148
148
|
|
149
|
+
@response.setter
|
150
|
+
def response(self, value: str) -> None:
|
151
|
+
"""
|
152
|
+
Set the assistant response content.
|
153
|
+
|
154
|
+
Args:
|
155
|
+
value: The new response content
|
156
|
+
"""
|
157
|
+
self.content["assistant_response"] = value
|
158
|
+
|
149
159
|
@property
|
150
160
|
def model_response(self) -> dict | list[dict]:
|
151
161
|
"""
|
@@ -498,6 +498,19 @@ class MessageManager:
|
|
498
498
|
]
|
499
499
|
)
|
500
500
|
|
501
|
+
def remove_last_instruction_tool_schemas(self) -> None:
|
502
|
+
id_ = self.last_instruction.ln_id
|
503
|
+
self.messages[id_].tool_schemas = None
|
504
|
+
|
505
|
+
def concat_recent_action_responses_to_instruction(
|
506
|
+
self, instruction: Instruction
|
507
|
+
) -> None:
|
508
|
+
for i in reversed(self.messages.progress):
|
509
|
+
if isinstance(self.messages[i], ActionResponse):
|
510
|
+
instruction.context.append(self.messages[i].content.to_dict())
|
511
|
+
else:
|
512
|
+
break
|
513
|
+
|
501
514
|
def to_chat_msgs(self, progress=None) -> list[dict]:
|
502
515
|
"""
|
503
516
|
Convert messages to chat format.
|
@@ -92,9 +92,11 @@ def format_text_item(item: Any) -> str:
|
|
92
92
|
for j in item:
|
93
93
|
if isinstance(j, dict):
|
94
94
|
for k, v in j.items():
|
95
|
-
|
95
|
+
if v is not None:
|
96
|
+
msg += f"- {k}: {v} \n\n"
|
96
97
|
else:
|
97
|
-
|
98
|
+
if j is not None:
|
99
|
+
msg += f"{j}\n"
|
98
100
|
return msg
|
99
101
|
|
100
102
|
|
@@ -33,6 +33,7 @@ from ..communication.types import (
|
|
33
33
|
ActionResponse,
|
34
34
|
AssistantResponse,
|
35
35
|
Instruction,
|
36
|
+
RoledMessage,
|
36
37
|
)
|
37
38
|
|
38
39
|
|
@@ -149,6 +150,8 @@ class BranchOperationMixin(ABC):
|
|
149
150
|
if auto_retry_parse is True:
|
150
151
|
operative.auto_retry_parse = True
|
151
152
|
|
153
|
+
if actions:
|
154
|
+
tools = tools or True
|
152
155
|
if invoke_actions and tools:
|
153
156
|
tool_schemas = self.get_tool_schema(tools)
|
154
157
|
|
@@ -275,7 +278,7 @@ class BranchOperationMixin(ABC):
|
|
275
278
|
**kwargs,
|
276
279
|
) -> tuple[Instruction, AssistantResponse]:
|
277
280
|
|
278
|
-
ins = self.msgs.create_instruction(
|
281
|
+
ins: Instruction = self.msgs.create_instruction(
|
279
282
|
instruction=instruction,
|
280
283
|
guidance=guidance,
|
281
284
|
context=context,
|
@@ -289,7 +292,57 @@ class BranchOperationMixin(ABC):
|
|
289
292
|
)
|
290
293
|
|
291
294
|
progress = progress or self.msgs.progress
|
292
|
-
messages
|
295
|
+
messages: list[RoledMessage] = [
|
296
|
+
self.msgs.messages[i] for i in progress
|
297
|
+
]
|
298
|
+
|
299
|
+
use_ins = None
|
300
|
+
if imodel.sequential_exchange:
|
301
|
+
_to_use = []
|
302
|
+
_action_responses: set[ActionResponse] = set()
|
303
|
+
|
304
|
+
for i in messages:
|
305
|
+
if isinstance(i, ActionResponse):
|
306
|
+
_action_responses.add(i)
|
307
|
+
if isinstance(i, AssistantResponse):
|
308
|
+
_to_use.append(i.model_copy())
|
309
|
+
if isinstance(i, Instruction):
|
310
|
+
if _action_responses:
|
311
|
+
j = i.model_copy()
|
312
|
+
d_ = [k.content.to_dict() for k in _action_responses]
|
313
|
+
for z in d_:
|
314
|
+
if z not in j.context:
|
315
|
+
j.context.append(z)
|
316
|
+
|
317
|
+
_to_use.append(j)
|
318
|
+
_action_responses = set()
|
319
|
+
else:
|
320
|
+
_to_use.append(i)
|
321
|
+
|
322
|
+
messages = _to_use
|
323
|
+
if _action_responses:
|
324
|
+
j = ins.model_copy()
|
325
|
+
d_ = [k.content.to_dict() for k in _action_responses]
|
326
|
+
for z in d_:
|
327
|
+
if z not in j.context:
|
328
|
+
j.context.append(z)
|
329
|
+
use_ins = j
|
330
|
+
|
331
|
+
if messages and len(messages) > 1:
|
332
|
+
_msgs = [messages[0]]
|
333
|
+
|
334
|
+
for i in messages[1:]:
|
335
|
+
if isinstance(i, AssistantResponse):
|
336
|
+
if isinstance(_msgs[-1], AssistantResponse):
|
337
|
+
_msgs[-1].response = (
|
338
|
+
f"{_msgs[-1].response}\n\n{i.response}"
|
339
|
+
)
|
340
|
+
else:
|
341
|
+
_msgs.append(i)
|
342
|
+
else:
|
343
|
+
if isinstance(_msgs[-1], AssistantResponse):
|
344
|
+
_msgs.append(i)
|
345
|
+
messages = _msgs
|
293
346
|
|
294
347
|
if self.msgs.system and "system" not in imodel.allowed_roles:
|
295
348
|
messages = [msg for msg in messages if msg.role != "system"]
|
@@ -312,9 +365,10 @@ class BranchOperationMixin(ABC):
|
|
312
365
|
first_instruction.guidance or ""
|
313
366
|
)
|
314
367
|
messages[0] = first_instruction
|
368
|
+
messages.append(use_ins or ins)
|
315
369
|
|
316
370
|
else:
|
317
|
-
messages.append(ins)
|
371
|
+
messages.append(use_ins or ins)
|
318
372
|
|
319
373
|
kwargs["messages"] = [i.chat_msg for i in messages]
|
320
374
|
imodel = imodel or self.imodel
|
@@ -331,6 +385,7 @@ class BranchOperationMixin(ABC):
|
|
331
385
|
sender=self,
|
332
386
|
recipient=self.user,
|
333
387
|
)
|
388
|
+
|
334
389
|
return ins, res
|
335
390
|
|
336
391
|
async def communicate(
|
@@ -346,7 +401,6 @@ class BranchOperationMixin(ABC):
|
|
346
401
|
imodel: iModel = None,
|
347
402
|
images: list = None,
|
348
403
|
image_detail: Literal["low", "high", "auto"] = None,
|
349
|
-
tools: str | FUNCTOOL | list[FUNCTOOL | str] | bool = None,
|
350
404
|
num_parse_retries: int = 0,
|
351
405
|
retry_imodel: iModel = None,
|
352
406
|
retry_kwargs: dict = {},
|
@@ -355,7 +409,6 @@ class BranchOperationMixin(ABC):
|
|
355
409
|
] = "return_value",
|
356
410
|
skip_validation: bool = False,
|
357
411
|
clear_messages: bool = False,
|
358
|
-
invoke_action: bool = True,
|
359
412
|
response_format: (
|
360
413
|
type[BaseModel] | BaseModel
|
361
414
|
) = None, # alias of request_model
|
@@ -380,10 +433,6 @@ class BranchOperationMixin(ABC):
|
|
380
433
|
)
|
381
434
|
num_parse_retries = 5
|
382
435
|
|
383
|
-
tool_schemas = None
|
384
|
-
if invoke_action and tools:
|
385
|
-
tool_schemas = self.get_tool_schema(tools)
|
386
|
-
|
387
436
|
ins, res = await self._invoke_imodel(
|
388
437
|
instruction=instruction,
|
389
438
|
guidance=guidance,
|
@@ -395,36 +444,14 @@ class BranchOperationMixin(ABC):
|
|
395
444
|
imodel=imodel,
|
396
445
|
images=images,
|
397
446
|
image_detail=image_detail,
|
398
|
-
tool_schemas=tool_schemas,
|
399
447
|
**kwargs,
|
400
448
|
)
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
action_request_models = None
|
405
|
-
action_response_models = None
|
449
|
+
self.msgs.add_message(instruction=ins)
|
450
|
+
self.msgs.add_message(assistant_response=res)
|
406
451
|
|
407
452
|
if skip_validation:
|
408
453
|
return res.response
|
409
454
|
|
410
|
-
if invoke_action and tools:
|
411
|
-
action_request_models = ActionRequestModel.create(res.response)
|
412
|
-
|
413
|
-
if action_request_models and invoke_action:
|
414
|
-
action_response_models = await alcall(
|
415
|
-
action_request_models,
|
416
|
-
self.invoke_action,
|
417
|
-
suppress_errors=True,
|
418
|
-
)
|
419
|
-
|
420
|
-
if action_request_models and not action_response_models:
|
421
|
-
for i in action_request_models:
|
422
|
-
await self.msgs.a_add_message(
|
423
|
-
action_request_model=i,
|
424
|
-
sender=self,
|
425
|
-
recipient=None,
|
426
|
-
)
|
427
|
-
|
428
455
|
_d = None
|
429
456
|
if request_fields is not None or request_model is not None:
|
430
457
|
parse_success = None
|
@@ -475,9 +502,12 @@ class BranchOperationMixin(ABC):
|
|
475
502
|
if _d and isinstance(_d, dict):
|
476
503
|
parse_success = True
|
477
504
|
if res not in self.msgs.messages:
|
478
|
-
|
479
|
-
|
480
|
-
)
|
505
|
+
if isinstance(
|
506
|
+
self.msgs.messages[-1], AssistantResponse
|
507
|
+
):
|
508
|
+
self.msgs.messages[-1].response = res.response
|
509
|
+
else:
|
510
|
+
self.msgs.add_message(assistant_response=res)
|
481
511
|
return _d
|
482
512
|
|
483
513
|
elif request_model:
|
@@ -495,9 +525,16 @@ class BranchOperationMixin(ABC):
|
|
495
525
|
_d = request_model.model_validate(_d)
|
496
526
|
parse_success = True
|
497
527
|
if res not in self.msgs.messages:
|
498
|
-
|
499
|
-
|
500
|
-
)
|
528
|
+
if isinstance(
|
529
|
+
self.msgs.messages[-1], AssistantResponse
|
530
|
+
):
|
531
|
+
self.msgs.messages[-1].response = (
|
532
|
+
res.response
|
533
|
+
)
|
534
|
+
else:
|
535
|
+
self.msgs.add_message(
|
536
|
+
assistant_response=res
|
537
|
+
)
|
501
538
|
return _d
|
502
539
|
except Exception as e:
|
503
540
|
logging.warning(
|
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)
|
@@ -4,6 +4,7 @@
|
|
4
4
|
|
5
5
|
from pathlib import Path
|
6
6
|
|
7
|
+
import yaml
|
7
8
|
from dotenv import load_dotenv
|
8
9
|
from pydantic import (
|
9
10
|
BaseModel,
|
@@ -33,12 +34,6 @@ price_config_file_name = path / "anthropic_price_data.yaml"
|
|
33
34
|
max_output_token_file_name = path / "anthropic_max_output_token_data.yaml"
|
34
35
|
|
35
36
|
|
36
|
-
class _ModuleImportClass:
|
37
|
-
from lionagi.libs.package.imports import check_import
|
38
|
-
|
39
|
-
yaml = check_import("yaml", pip_name="pyyaml")
|
40
|
-
|
41
|
-
|
42
37
|
class AnthropicModel(BaseModel):
|
43
38
|
model: str = Field(description="ID of the model to use.")
|
44
39
|
|
@@ -239,7 +234,7 @@ class AnthropicModel(BaseModel):
|
|
239
234
|
)
|
240
235
|
if estimated_output_len == 0:
|
241
236
|
with open(max_output_token_file_name) as file:
|
242
|
-
output_token_config =
|
237
|
+
output_token_config = yaml.safe_load(file)
|
243
238
|
estimated_output_len = output_token_config.get(self.model, 0)
|
244
239
|
self.estimated_output_len = estimated_output_len
|
245
240
|
|
@@ -261,13 +256,13 @@ class AnthropicModel(BaseModel):
|
|
261
256
|
num_of_input_tokens = self.text_token_calculator.calculate(input_text)
|
262
257
|
|
263
258
|
with open(price_config_file_name) as file:
|
264
|
-
price_config =
|
259
|
+
price_config = yaml.safe_load(file)
|
265
260
|
|
266
261
|
model_price_info_dict = price_config["model"][self.model]
|
267
262
|
estimated_price = (
|
268
263
|
model_price_info_dict["input_tokens"] * num_of_input_tokens
|
269
264
|
+ model_price_info_dict["output_tokens"]
|
270
265
|
* estimated_num_of_output_tokens
|
271
|
-
)
|
266
|
+
) / 1_000_000
|
272
267
|
|
273
268
|
return estimated_price
|
@@ -51,6 +51,11 @@ class AnthropicService(Service):
|
|
51
51
|
# Map model versions to their base models for shared rate limiting
|
52
52
|
shared_models = {
|
53
53
|
"claude-3-opus-20240229": "claude-3-opus",
|
54
|
+
"claude-3-sonnet-20241022": "claude-3-sonnet",
|
55
|
+
"claude-3-haiku-20241022": "claude-3-haiku",
|
56
|
+
"claude-3-opus-latest": "claude-3-opus",
|
57
|
+
"claude-3-sonnet-latest": "claude-3-sonnet",
|
58
|
+
"claude-3-haiku-latest": "claude-3-haiku",
|
54
59
|
"claude-3-sonnet-20240229": "claude-3-sonnet",
|
55
60
|
"claude-3-haiku-20240307": "claude-3-haiku",
|
56
61
|
}
|
@@ -115,3 +120,8 @@ class AnthropicService(Service):
|
|
115
120
|
@property
|
116
121
|
def allowed_roles(self):
|
117
122
|
return ["user", "assistant"]
|
123
|
+
|
124
|
+
@property
|
125
|
+
def sequential_exchange(self):
|
126
|
+
"""whether the service requires user/assistant exchange"""
|
127
|
+
return True
|
@@ -2,6 +2,11 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
|
+
claude-3-5-sonnet-20241022: 8192 # Latest model
|
6
|
+
claude-3-5-haiku-20241022: 8192 # Latest model
|
5
7
|
claude-3-opus-20240229: 4096
|
6
8
|
claude-3-sonnet-20240229: 4096
|
7
9
|
claude-3-haiku-20240307: 4096
|
10
|
+
claude-2.1: 4096
|
11
|
+
claude-2.0: 4096
|
12
|
+
claude-instant-1.2: 4096
|
@@ -3,12 +3,32 @@
|
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
5
|
model:
|
6
|
+
# Latest Models (3.5 series)
|
7
|
+
claude-3-5-sonnet-20241022:
|
8
|
+
input_tokens: 3.0
|
9
|
+
output_tokens: 15.0
|
10
|
+
claude-3-5-haiku-20241022:
|
11
|
+
input_tokens: 0.80
|
12
|
+
output_tokens: 4.0
|
13
|
+
|
14
|
+
# Claude 3 Models
|
6
15
|
claude-3-opus-20240229:
|
7
|
-
input_tokens: 0
|
8
|
-
output_tokens: 0
|
16
|
+
input_tokens: 15.0
|
17
|
+
output_tokens: 75.0
|
9
18
|
claude-3-sonnet-20240229:
|
10
|
-
input_tokens: 0
|
11
|
-
output_tokens: 0
|
19
|
+
input_tokens: 3.0
|
20
|
+
output_tokens: 15.0
|
12
21
|
claude-3-haiku-20240307:
|
13
|
-
input_tokens: 0.
|
14
|
-
output_tokens:
|
22
|
+
input_tokens: 0.25
|
23
|
+
output_tokens: 1.25
|
24
|
+
|
25
|
+
# Legacy Models
|
26
|
+
claude-2.1:
|
27
|
+
input_tokens: 8.0
|
28
|
+
output_tokens: 24.0
|
29
|
+
claude-2.0:
|
30
|
+
input_tokens: 8.0
|
31
|
+
output_tokens: 24.0
|
32
|
+
claude-instant-1.2:
|
33
|
+
input_tokens: 0.8
|
34
|
+
output_tokens: 2.4
|
@@ -424,3 +424,12 @@ class OpenAIService(Service):
|
|
424
424
|
method="POST",
|
425
425
|
content_type="application/json",
|
426
426
|
)
|
427
|
+
|
428
|
+
@property
|
429
|
+
def allowed_roles(self):
|
430
|
+
return ["user", "assistant", "system"]
|
431
|
+
|
432
|
+
@property
|
433
|
+
def sequential_exchange(self):
|
434
|
+
"""whether the service requires user/assistant exchange"""
|
435
|
+
return False
|
@@ -1 +1 @@
|
|
1
|
-
__version__ = "1.0.
|
1
|
+
__version__ = "1.0.3"
|
@@ -1 +1 @@
|
|
1
|
-
__version__ = "1.0.
|
1
|
+
__version__ = "1.0.1"
|
@@ -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 "
|