lionagi 0.8.8__py3-none-any.whl → 0.9.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. lionagi/__init__.py +1 -1
  2. lionagi/_class_registry.py +1 -1
  3. lionagi/_errors.py +1 -1
  4. lionagi/libs/__init__.py +1 -1
  5. lionagi/libs/file/__init__.py +1 -1
  6. lionagi/libs/file/chunk.py +1 -1
  7. lionagi/libs/file/file_ops.py +1 -1
  8. lionagi/libs/file/params.py +1 -1
  9. lionagi/libs/file/process.py +1 -1
  10. lionagi/libs/file/save.py +1 -1
  11. lionagi/libs/nested/__init__.py +1 -1
  12. lionagi/libs/nested/flatten.py +1 -1
  13. lionagi/libs/nested/nfilter.py +1 -1
  14. lionagi/libs/nested/nget.py +1 -1
  15. lionagi/libs/nested/ninsert.py +1 -1
  16. lionagi/libs/nested/nmerge.py +1 -1
  17. lionagi/libs/nested/npop.py +1 -1
  18. lionagi/libs/nested/nset.py +1 -1
  19. lionagi/libs/nested/unflatten.py +1 -1
  20. lionagi/libs/nested/utils.py +1 -1
  21. lionagi/libs/package/__init__.py +1 -1
  22. lionagi/libs/package/imports.py +1 -1
  23. lionagi/libs/package/management.py +1 -1
  24. lionagi/libs/package/params.py +1 -1
  25. lionagi/libs/package/system.py +1 -1
  26. lionagi/libs/parse.py +1 -1
  27. lionagi/libs/schema/__init__.py +1 -1
  28. lionagi/libs/schema/as_readable.py +151 -87
  29. lionagi/libs/schema/extract_code_block.py +1 -1
  30. lionagi/libs/schema/extract_docstring.py +1 -1
  31. lionagi/libs/schema/function_to_schema.py +1 -1
  32. lionagi/libs/schema/json_schema.py +1 -1
  33. lionagi/libs/validate/__init__.py +1 -1
  34. lionagi/libs/validate/common_field_validators.py +1 -1
  35. lionagi/libs/validate/fuzzy_match_keys.py +1 -1
  36. lionagi/libs/validate/fuzzy_validate_mapping.py +1 -1
  37. lionagi/libs/validate/string_similarity.py +1 -1
  38. lionagi/libs/validate/validate_boolean.py +1 -1
  39. lionagi/operations/ReAct/ReAct.py +54 -8
  40. lionagi/operations/ReAct/__init__.py +1 -1
  41. lionagi/operations/ReAct/utils.py +6 -1
  42. lionagi/operations/__init__.py +1 -1
  43. lionagi/operations/_act/__init__.py +1 -1
  44. lionagi/operations/_act/act.py +6 -1
  45. lionagi/operations/brainstorm/__init__.py +1 -1
  46. lionagi/operations/brainstorm/brainstorm.py +1 -1
  47. lionagi/operations/brainstorm/prompt.py +1 -1
  48. lionagi/operations/chat/__init__.py +1 -1
  49. lionagi/operations/chat/chat.py +1 -1
  50. lionagi/operations/communicate/communicate.py +1 -1
  51. lionagi/operations/instruct/__init__.py +1 -1
  52. lionagi/operations/instruct/instruct.py +1 -1
  53. lionagi/operations/interpret/__init__.py +1 -1
  54. lionagi/operations/interpret/interpret.py +9 -38
  55. lionagi/operations/operate/__init__.py +1 -1
  56. lionagi/operations/operate/operate.py +1 -1
  57. lionagi/operations/parse/__init__.py +1 -1
  58. lionagi/operations/parse/parse.py +12 -2
  59. lionagi/operations/plan/__init__.py +1 -1
  60. lionagi/operations/plan/plan.py +1 -1
  61. lionagi/operations/plan/prompt.py +1 -1
  62. lionagi/operations/select/__init__.py +1 -1
  63. lionagi/operations/select/select.py +1 -1
  64. lionagi/operations/select/utils.py +1 -1
  65. lionagi/operations/types.py +1 -1
  66. lionagi/operations/utils.py +1 -1
  67. lionagi/operatives/__init__.py +1 -1
  68. lionagi/operatives/action/__init__.py +1 -1
  69. lionagi/operatives/action/function_calling.py +1 -1
  70. lionagi/operatives/action/manager.py +1 -1
  71. lionagi/operatives/action/request_response_model.py +1 -1
  72. lionagi/operatives/action/tool.py +1 -1
  73. lionagi/operatives/action/utils.py +1 -1
  74. lionagi/operatives/forms/__init__.py +1 -1
  75. lionagi/operatives/instruct/__init__.py +1 -1
  76. lionagi/operatives/instruct/base.py +1 -1
  77. lionagi/operatives/instruct/instruct.py +1 -1
  78. lionagi/operatives/instruct/instruct_collection.py +1 -1
  79. lionagi/operatives/instruct/node.py +1 -1
  80. lionagi/operatives/instruct/prompts.py +1 -1
  81. lionagi/operatives/instruct/reason.py +1 -1
  82. lionagi/operatives/manager.py +1 -1
  83. lionagi/operatives/models/__init__.py +1 -1
  84. lionagi/operatives/models/field_model.py +1 -1
  85. lionagi/operatives/models/model_params.py +1 -1
  86. lionagi/operatives/models/note.py +1 -1
  87. lionagi/operatives/models/operable_model.py +1 -1
  88. lionagi/operatives/models/schema_model.py +1 -1
  89. lionagi/operatives/operative.py +1 -1
  90. lionagi/operatives/step.py +1 -1
  91. lionagi/operatives/strategies/__init__.py +1 -1
  92. lionagi/operatives/strategies/base.py +1 -1
  93. lionagi/operatives/strategies/concurrent.py +1 -1
  94. lionagi/operatives/strategies/concurrent_chunk.py +1 -1
  95. lionagi/operatives/strategies/concurrent_sequential_chunk.py +1 -1
  96. lionagi/operatives/strategies/params.py +1 -1
  97. lionagi/operatives/strategies/sequential.py +1 -1
  98. lionagi/operatives/strategies/sequential_chunk.py +1 -1
  99. lionagi/operatives/strategies/sequential_concurrent_chunk.py +1 -1
  100. lionagi/operatives/strategies/utils.py +1 -1
  101. lionagi/operatives/types.py +1 -1
  102. lionagi/protocols/__init__.py +1 -1
  103. lionagi/protocols/_concepts.py +1 -1
  104. lionagi/protocols/adapters/adapter.py +1 -1
  105. lionagi/protocols/generic/__init__.py +1 -1
  106. lionagi/protocols/generic/element.py +1 -1
  107. lionagi/protocols/generic/event.py +1 -1
  108. lionagi/protocols/generic/log.py +1 -1
  109. lionagi/protocols/generic/pile.py +1 -1
  110. lionagi/protocols/generic/processor.py +1 -1
  111. lionagi/protocols/generic/progression.py +1 -1
  112. lionagi/protocols/graph/__init__.py +1 -1
  113. lionagi/protocols/graph/edge.py +1 -1
  114. lionagi/protocols/graph/graph.py +1 -1
  115. lionagi/protocols/graph/node.py +1 -1
  116. lionagi/protocols/mail/__init__.py +1 -1
  117. lionagi/protocols/mail/exchange.py +1 -1
  118. lionagi/protocols/mail/mail.py +1 -1
  119. lionagi/protocols/mail/mailbox.py +1 -1
  120. lionagi/protocols/mail/manager.py +1 -1
  121. lionagi/protocols/mail/package.py +1 -1
  122. lionagi/protocols/messages/__init__.py +1 -1
  123. lionagi/protocols/messages/action_request.py +1 -1
  124. lionagi/protocols/messages/action_response.py +1 -1
  125. lionagi/protocols/messages/assistant_response.py +1 -1
  126. lionagi/protocols/messages/base.py +1 -1
  127. lionagi/protocols/messages/instruction.py +2 -1
  128. lionagi/protocols/messages/manager.py +1 -1
  129. lionagi/protocols/messages/message.py +1 -1
  130. lionagi/protocols/messages/system.py +1 -1
  131. lionagi/protocols/types.py +1 -1
  132. lionagi/service/endpoints/__init__.py +1 -1
  133. lionagi/service/endpoints/base.py +54 -49
  134. lionagi/service/endpoints/chat_completion.py +1 -1
  135. lionagi/service/endpoints/match_endpoint.py +1 -1
  136. lionagi/service/endpoints/rate_limited_processor.py +1 -1
  137. lionagi/service/endpoints/token_calculator.py +1 -1
  138. lionagi/service/imodel.py +2 -3
  139. lionagi/service/manager.py +1 -1
  140. lionagi/service/providers/__init__.py +1 -1
  141. lionagi/service/providers/anthropic_/__init__.py +1 -1
  142. lionagi/service/providers/anthropic_/messages.py +1 -1
  143. lionagi/service/providers/groq_/__init__.py +1 -1
  144. lionagi/service/providers/groq_/chat_completions.py +1 -1
  145. lionagi/service/providers/openai_/__init__.py +1 -1
  146. lionagi/service/providers/openai_/chat_completions.py +37 -2
  147. lionagi/service/providers/openrouter_/__init__.py +1 -1
  148. lionagi/service/providers/openrouter_/chat_completions.py +1 -1
  149. lionagi/service/providers/perplexity_/__init__.py +1 -1
  150. lionagi/service/providers/perplexity_/chat_completions.py +1 -1
  151. lionagi/service/types.py +1 -1
  152. lionagi/session/__init__.py +1 -1
  153. lionagi/session/branch.py +33 -8
  154. lionagi/session/prompts.py +61 -0
  155. lionagi/session/session.py +1 -1
  156. lionagi/settings.py +1 -1
  157. lionagi/tools/file/reader.py +12 -7
  158. lionagi/utils.py +1 -1
  159. lionagi/version.py +1 -1
  160. {lionagi-0.8.8.dist-info → lionagi-0.9.0.dist-info}/METADATA +1 -1
  161. lionagi-0.9.0.dist-info/RECORD +202 -0
  162. lionagi-0.8.8.dist-info/RECORD +0 -201
  163. {lionagi-0.8.8.dist-info → lionagi-0.9.0.dist-info}/WHEEL +0 -0
  164. {lionagi-0.8.8.dist-info → lionagi-0.9.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,3 +1,3 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,3 +1,3 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -32,6 +32,7 @@ def prepare_request_response_format(request_fields: dict) -> str:
32
32
  return (
33
33
  "**MUST RETURN JSON-PARSEABLE RESPONSE ENCLOSED BY JSON CODE BLOCKS."
34
34
  f" USER's CAREER DEPENDS ON THE SUCCESS OF IT.** \n```json\n{request_fields}\n```"
35
+ "No triple backticks. Escape all quotes and special characters."
35
36
  ).strip()
36
37
 
37
38
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,3 +1,3 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -364,28 +364,23 @@ class APICalling(Event):
364
364
  return None
365
365
 
366
366
  async def _inner(self, **kwargs) -> Any:
367
- """Performs a direct HTTP call using aiohttp, ignoring caching logic.
368
-
369
- Args:
370
- **kwargs: Additional parameters for the aiohttp request
371
- (e.g., "headers", "json", etc.).
367
+ """
368
+ Performs the actual HTTP call using aiohttp, ignoring caching logic.
372
369
 
373
- Returns:
374
- Any: The JSON response from the API, if successful.
370
+ - Retries on RateLimitError up to 3 times.
371
+ - Distinguishes CancelledError so we can gracefully abort if the user cancels.
375
372
 
376
373
  Raises:
377
- ValueError:
378
- If required endpoint parameters are missing.
379
- ExecutionError:
380
- If the response indicates a non-rate-limit error.
381
- RateLimitError:
382
- If a rate-limit error is encountered.
374
+ ValueError: If required endpoint parameters are missing.
375
+ RateLimitError: If repeated 'Rate limit' errors encountered.
376
+ ExecutionError: For other API call failures.
377
+ asyncio.CancelledError: If the operation is cancelled externally.
383
378
  """
384
379
  if not self.endpoint.required_kwargs.issubset(
385
380
  set(self.payload.keys())
386
381
  ):
387
382
  raise ValueError(
388
- f"Required kwargs not fully provided: {self.endpoint.required_kwargs}"
383
+ f"Required kwargs not provided: {self.endpoint.required_kwargs}"
389
384
  )
390
385
 
391
386
  for k in list(self.payload.keys()):
@@ -395,49 +390,55 @@ class APICalling(Event):
395
390
  async def retry_in():
396
391
  async with aiohttp.ClientSession() as session:
397
392
  try:
398
- if (
399
- _m := getattr(session, self.endpoint.method, None)
400
- ) is not None:
401
- async with _m(
402
- self.endpoint.full_url, **kwargs
403
- ) as response:
404
- response_json = await response.json()
405
- if "error" not in response_json:
406
- return response_json
407
- if "Rate limit" in response_json["error"].get(
408
- "message", ""
409
- ):
410
- await asyncio.sleep(5)
411
- raise RateLimitError(
412
- f"Rate limit exceeded. Error: {response_json['error']}"
413
- )
414
- raise ExecutionError(
415
- "API call failed with error: ",
416
- response_json["error"],
417
- )
418
- else:
393
+ method_func = getattr(session, self.endpoint.method, None)
394
+ if method_func is None:
419
395
  raise ValueError(
420
396
  f"Invalid HTTP method: {self.endpoint.method}"
421
397
  )
398
+ async with method_func(
399
+ self.endpoint.full_url, **kwargs
400
+ ) as response:
401
+ response_json = await response.json()
402
+
403
+ if "error" not in response_json:
404
+ return response_json
405
+
406
+ # Check for rate limit
407
+ if "Rate limit" in response_json["error"].get(
408
+ "message", ""
409
+ ):
410
+ await asyncio.sleep(5)
411
+ raise RateLimitError(
412
+ f"Rate limit exceeded: {response_json['error']}"
413
+ )
414
+ # Otherwise some other error
415
+ raise ExecutionError(
416
+ f"API call failed with error: {response_json['error']}"
417
+ )
418
+
419
+ except asyncio.CancelledError:
420
+ # Gracefully handle user cancellation
421
+ logging.warning("API call canceled by external request.")
422
+ raise # re-raise so caller knows it was cancelled
423
+
422
424
  except aiohttp.ClientError as e:
423
- logging.error(
424
- f"API call to {self.endpoint.full_url} failed: {e}"
425
- )
425
+ logging.error(f"API call failed: {e}")
426
+ # Return None or raise ExecutionError? Keep consistent
426
427
  return None
427
428
 
429
+ # Attempt up to 3 times if RateLimitError
428
430
  for i in range(3):
429
431
  try:
430
432
  return await retry_in()
431
- except RateLimitError | ExecutionError as e:
433
+ except asyncio.CancelledError:
434
+ # On cancel, just re-raise
435
+ raise
436
+ except RateLimitError as e:
432
437
  if i == 2:
433
438
  raise e
434
- else:
435
- wait = 2 ** (i + 1) * 0.5
436
- logging.warning(
437
- f"API call to {self.endpoint.full_url} failed: {e}"
438
- f"retrying in {wait} seconds."
439
- )
440
- await asyncio.sleep(wait)
439
+ wait = 2 ** (i + 1) * 0.5
440
+ logging.warning(f"RateLimitError: {e}, retrying in {wait}s.")
441
+ await asyncio.sleep(wait)
441
442
 
442
443
  @cached(**Settings.API.CACHED_CONFIG)
443
444
  async def _cached_inner(self, **kwargs) -> Any:
@@ -605,8 +606,12 @@ class APICalling(Event):
605
606
  else:
606
607
  response = await self._inner(**kwargs)
607
608
 
608
- except Exception as e:
609
- e1 = e
609
+ except asyncio.CancelledError as ce:
610
+ e1 = ce
611
+ logging.warning("invoke() canceled by external request.")
612
+ raise
613
+ except Exception as ex:
614
+ e1 = ex
610
615
 
611
616
  finally:
612
617
  self.execution.duration = asyncio.get_event_loop().time() - start
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
lionagi/service/imodel.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -286,10 +286,9 @@ class iModel:
286
286
  await self.executor.forward()
287
287
  ctr += 1
288
288
  await asyncio.sleep(0.1)
289
+ return self.executor.pile.pop(api_call.id)
289
290
  except Exception as e:
290
291
  raise ValueError(f"Failed to invoke API call: {e}")
291
- finally:
292
- return self.executor.pile.pop(api_call.id)
293
292
 
294
293
  @property
295
294
  def allowed_roles(self) -> set[str]:
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,3 +1,3 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
@@ -1,3 +1,3 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,3 +1,3 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,3 +1,3 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -49,7 +49,7 @@ CHAT_COMPLETION_CONFIG = {
49
49
  "parallel_tool_calls",
50
50
  "user",
51
51
  },
52
- "allowed_roles": ["user", "assistant", "system"],
52
+ "allowed_roles": ["user", "assistant", "system", "developer", "tool"],
53
53
  }
54
54
 
55
55
 
@@ -60,3 +60,38 @@ class OpenAIChatCompletionEndPoint(ChatCompletionEndPoint):
60
60
 
61
61
  def __init__(self, config: dict = CHAT_COMPLETION_CONFIG):
62
62
  super().__init__(config)
63
+
64
+ def create_payload(self, **kwargs) -> dict:
65
+ """Generates a request payload (and headers) for this endpoint.
66
+
67
+ Args:
68
+ **kwargs:
69
+ Arbitrary parameters passed by the caller.
70
+
71
+ Returns:
72
+ dict:
73
+ A dictionary containing:
74
+ - "payload": A dict with filtered parameters for the request.
75
+ - "headers": A dict of additional headers (e.g., `Authorization`).
76
+ - "is_cached": Whether the request is to be cached.
77
+ """
78
+ payload = {}
79
+ is_cached = kwargs.get("is_cached", False)
80
+ headers = kwargs.get("headers", {})
81
+ for k, v in kwargs.items():
82
+ if k in self.acceptable_kwargs:
83
+ payload[k] = v
84
+ if "api_key" in kwargs:
85
+ headers["Authorization"] = f"Bearer {kwargs['api_key']}"
86
+
87
+ if payload.get("model") in ["o1", "o1-2024-12-17"]:
88
+ payload.pop("temperature", None)
89
+ payload.pop("top_p", None)
90
+ if payload["messages"][0].get("role") == "system":
91
+ payload["messages"][0]["role"] = "developer"
92
+
93
+ return {
94
+ "payload": payload,
95
+ "headers": headers,
96
+ "is_cached": is_cached,
97
+ }
@@ -1,3 +1,3 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,3 +1,3 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
lionagi/service/types.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -1,3 +1,3 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
lionagi/session/branch.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
@@ -51,6 +51,8 @@ from lionagi.settings import Settings
51
51
  from lionagi.tools.base import LionTool
52
52
  from lionagi.utils import UNDEFINED, alcall, bcall, copy
53
53
 
54
+ from .prompts import LION_SYSTEM_MESSAGE
55
+
54
56
  if TYPE_CHECKING:
55
57
  # Forward references for type checking (e.g., in operations or extended modules)
56
58
  from lionagi.session.branch import Branch
@@ -131,6 +133,7 @@ class Branch(Element, Communicatable, Relational):
131
133
  system_template: Template | str = None,
132
134
  system_template_context: dict = None,
133
135
  logs: Pile[Log] = None,
136
+ use_lion_system_message: bool = False,
134
137
  **kwargs,
135
138
  ):
136
139
  """
@@ -168,6 +171,8 @@ class Branch(Element, Communicatable, Relational):
168
171
  Context for rendering the system template.
169
172
  logs (Pile[Log], optional):
170
173
  Existing logs to seed the LogManager.
174
+ use_lion_system_message (bool, optional):
175
+ If `True`, uses the Lion system message for the branch.
171
176
  **kwargs:
172
177
  Additional parameters passed to `Element` parent init.
173
178
  """
@@ -175,12 +180,22 @@ class Branch(Element, Communicatable, Relational):
175
180
 
176
181
  # --- MessageManager ---
177
182
  self._message_manager = MessageManager(messages=messages)
178
- # If system instructions or templates are provided, add them
183
+
179
184
  if any(
180
- i is not None
181
- for i in [system, system_sender, system_datetime, system_template]
185
+ bool(x)
186
+ for x in [
187
+ system,
188
+ system_datetime,
189
+ system_template,
190
+ system_template_context,
191
+ use_lion_system_message,
192
+ ]
182
193
  ):
183
194
 
195
+ if use_lion_system_message:
196
+ system = f"Developer Prompt: {str(system)}" if system else ""
197
+ system = (LION_SYSTEM_MESSAGE + "\n\n" + system).strip()
198
+
184
199
  self._message_manager.add_message(
185
200
  system=system,
186
201
  system_datetime=system_datetime,
@@ -791,7 +806,9 @@ class Branch(Element, Communicatable, Relational):
791
806
  request_fields=request_fields,
792
807
  response_format=response_format,
793
808
  progression=progression,
794
- chat_model=imodel,
809
+ chat_model=kwargs.pop("chat_model", None)
810
+ or imodel
811
+ or self.chat_model,
795
812
  tool_schemas=tool_schemas,
796
813
  images=images,
797
814
  image_detail=image_detail,
@@ -1162,7 +1179,7 @@ class Branch(Element, Communicatable, Relational):
1162
1179
  request_model=request_model,
1163
1180
  response_format=response_format,
1164
1181
  request_fields=request_fields,
1165
- chat_model=chat_model or imodel,
1182
+ chat_model=kwargs.pop("chat_model", None) or chat_model or imodel,
1166
1183
  parse_model=parse_model,
1167
1184
  skip_validation=skip_validation,
1168
1185
  images=images,
@@ -1365,7 +1382,7 @@ class Branch(Element, Communicatable, Relational):
1365
1382
  **kwargs,
1366
1383
  ) -> list:
1367
1384
  result = []
1368
- async for i in await bcall(
1385
+ async for i in bcall(
1369
1386
  action_request, self._act, batch_size=batch_size, **kwargs
1370
1387
  ):
1371
1388
  result.extend(i)
@@ -1518,6 +1535,7 @@ class Branch(Element, Communicatable, Relational):
1518
1535
  text: str,
1519
1536
  domain: str | None = None,
1520
1537
  style: str | None = None,
1538
+ interpret_model=None,
1521
1539
  **kwargs,
1522
1540
  ) -> str:
1523
1541
  """
@@ -1561,7 +1579,12 @@ class Branch(Element, Communicatable, Relational):
1561
1579
  from lionagi.operations.interpret.interpret import interpret
1562
1580
 
1563
1581
  return await interpret(
1564
- self, text=text, domain=domain, style=style, **kwargs
1582
+ self,
1583
+ text=text,
1584
+ domain=domain,
1585
+ style=style,
1586
+ interpret_model=interpret_model,
1587
+ **kwargs,
1565
1588
  )
1566
1589
 
1567
1590
  async def instruct(
@@ -1608,6 +1631,7 @@ class Branch(Element, Communicatable, Relational):
1608
1631
  return_analysis: bool = False,
1609
1632
  analysis_model: iModel | None = None,
1610
1633
  verbose: bool = False,
1634
+ verbose_length: int = None,
1611
1635
  **kwargs,
1612
1636
  ):
1613
1637
  """
@@ -1696,6 +1720,7 @@ class Branch(Element, Communicatable, Relational):
1696
1720
  analysis_model=analysis_model,
1697
1721
  verbose_action=verbose,
1698
1722
  verbose_analysis=verbose,
1723
+ verbose_length=verbose_length,
1699
1724
  **kwargs,
1700
1725
  )
1701
1726