lionagi 0.15.13__py3-none-any.whl → 0.16.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 (42) hide show
  1. lionagi/config.py +1 -0
  2. lionagi/libs/validate/fuzzy_match_keys.py +5 -182
  3. lionagi/libs/validate/string_similarity.py +6 -331
  4. lionagi/ln/__init__.py +56 -66
  5. lionagi/ln/_async_call.py +13 -10
  6. lionagi/ln/_hash.py +33 -8
  7. lionagi/ln/_list_call.py +2 -35
  8. lionagi/ln/_to_list.py +51 -28
  9. lionagi/ln/_utils.py +156 -0
  10. lionagi/ln/concurrency/__init__.py +39 -31
  11. lionagi/ln/concurrency/_compat.py +65 -0
  12. lionagi/ln/concurrency/cancel.py +92 -109
  13. lionagi/ln/concurrency/errors.py +17 -17
  14. lionagi/ln/concurrency/patterns.py +249 -206
  15. lionagi/ln/concurrency/primitives.py +257 -216
  16. lionagi/ln/concurrency/resource_tracker.py +42 -155
  17. lionagi/ln/concurrency/task.py +55 -73
  18. lionagi/ln/concurrency/throttle.py +3 -0
  19. lionagi/ln/concurrency/utils.py +1 -0
  20. lionagi/ln/fuzzy/__init__.py +15 -0
  21. lionagi/ln/{_extract_json.py → fuzzy/_extract_json.py} +22 -9
  22. lionagi/ln/{_fuzzy_json.py → fuzzy/_fuzzy_json.py} +14 -8
  23. lionagi/ln/fuzzy/_fuzzy_match.py +172 -0
  24. lionagi/ln/fuzzy/_fuzzy_validate.py +46 -0
  25. lionagi/ln/fuzzy/_string_similarity.py +332 -0
  26. lionagi/ln/{_models.py → types.py} +153 -4
  27. lionagi/operations/flow.py +2 -1
  28. lionagi/operations/operate/operate.py +26 -16
  29. lionagi/protocols/contracts.py +46 -0
  30. lionagi/protocols/generic/event.py +6 -6
  31. lionagi/protocols/generic/processor.py +9 -5
  32. lionagi/protocols/ids.py +82 -0
  33. lionagi/protocols/types.py +10 -12
  34. lionagi/service/connections/match_endpoint.py +9 -0
  35. lionagi/service/connections/providers/nvidia_nim_.py +100 -0
  36. lionagi/utils.py +34 -64
  37. lionagi/version.py +1 -1
  38. {lionagi-0.15.13.dist-info → lionagi-0.16.0.dist-info}/METADATA +4 -2
  39. {lionagi-0.15.13.dist-info → lionagi-0.16.0.dist-info}/RECORD +41 -33
  40. lionagi/ln/_types.py +0 -146
  41. {lionagi-0.15.13.dist-info → lionagi-0.16.0.dist-info}/WHEEL +0 -0
  42. {lionagi-0.15.13.dist-info → lionagi-0.16.0.dist-info}/licenses/LICENSE +0 -0
@@ -12,7 +12,8 @@ using Events for synchronization and CapacityLimiter for concurrency control.
12
12
  import os
13
13
  from typing import Any
14
14
 
15
- from lionagi.ln import AlcallParams, CapacityLimiter, ConcurrencyEvent
15
+ from lionagi.ln._async_call import AlcallParams
16
+ from lionagi.ln.concurrency import CapacityLimiter, ConcurrencyEvent
16
17
  from lionagi.operations.node import Operation
17
18
  from lionagi.protocols.types import EventStatus, Graph
18
19
  from lionagi.session.branch import Branch
@@ -23,6 +23,29 @@ if TYPE_CHECKING:
23
23
  from lionagi.session.branch import Branch
24
24
 
25
25
 
26
+ def _handle_response_format_kwargs(
27
+ operative_model: type[BaseModel] = None,
28
+ request_model: type[BaseModel] = None,
29
+ response_format: type[BaseModel] = None,
30
+ ):
31
+ if operative_model:
32
+ logging.warning(
33
+ "`operative_model` is deprecated. Use `response_format` instead."
34
+ )
35
+ if (
36
+ (operative_model and response_format)
37
+ or (operative_model and request_model)
38
+ or (response_format and request_model)
39
+ ):
40
+ raise ValueError(
41
+ "Cannot specify both `operative_model` and `response_format` (or `request_model`) "
42
+ "as they are aliases of each other."
43
+ )
44
+
45
+ # Use the final chosen format
46
+ return response_format or operative_model or request_model
47
+
48
+
26
49
  async def operate(
27
50
  branch: "Branch",
28
51
  *,
@@ -66,22 +89,9 @@ async def operate(
66
89
  include_token_usage_to_model: bool = False,
67
90
  **kwargs,
68
91
  ) -> list | BaseModel | None | dict | str:
69
- if operative_model:
70
- logging.warning(
71
- "`operative_model` is deprecated. Use `response_format` instead."
72
- )
73
- if (
74
- (operative_model and response_format)
75
- or (operative_model and request_model)
76
- or (response_format and request_model)
77
- ):
78
- raise ValueError(
79
- "Cannot specify both `operative_model` and `response_format` (or `request_model`) "
80
- "as they are aliases of each other."
81
- )
82
-
83
- # Use the final chosen format
84
- response_format = response_format or operative_model or request_model
92
+ response_format = _handle_response_format_kwargs(
93
+ operative_model, request_model, response_format
94
+ )
85
95
 
86
96
  # Decide which chat model to use
87
97
  chat_model = chat_model or imodel or branch.chat_model
@@ -0,0 +1,46 @@
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """V1 Observable Protocol for gradual evolution.
6
+
7
+ This module provides the runtime-checkable ObservableProto for V1 components
8
+ while maintaining compatibility with V0's nominal Observable ABC.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from typing import Protocol, runtime_checkable
14
+
15
+ __all__ = (
16
+ "ObservableProto",
17
+ "Observable",
18
+ "LegacyObservable",
19
+ )
20
+
21
+
22
+ @runtime_checkable
23
+ class ObservableProto(Protocol):
24
+ """Structural Observable Protocol for V1 components.
25
+
26
+ This protocol defines the minimal contract for observable objects:
27
+ they must have an 'id' property. The return type is permissive (Any)
28
+ to maintain compatibility with V0's IDType wrapper while enabling
29
+ V1 evolution.
30
+
31
+ All V0 Element subclasses automatically satisfy this protocol without
32
+ any code changes, enabling zero-risk gradual migration.
33
+ """
34
+
35
+ @property
36
+ def id(self) -> object:
37
+ """Unique identifier. Accepts IDType, UUID, or string."""
38
+ ...
39
+
40
+
41
+ # Convenience alias for V1 consumers (keeps import names short)
42
+ Observable = ObservableProto
43
+
44
+ # Keep legacy nominal ABC for places that need issubclass checks (e.g., Pile)
45
+ # Do NOT remove – Pile and others rely on issubclass(..., Observable) nominal checks.
46
+ from ._concepts import Observable as LegacyObservable
@@ -5,13 +5,13 @@
5
5
  from __future__ import annotations
6
6
 
7
7
  import contextlib
8
- from enum import Enum
8
+ from enum import Enum as _Enum
9
9
  from typing import Any
10
10
 
11
11
  from pydantic import Field, field_serializer
12
12
 
13
13
  from lionagi import ln
14
- from lionagi.utils import to_dict
14
+ from lionagi.utils import Unset, to_dict
15
15
 
16
16
  from .element import Element
17
17
 
@@ -22,10 +22,10 @@ __all__ = (
22
22
  )
23
23
 
24
24
 
25
- _SIMPLE_TYPE = (str, bytes, bytearray, int, float, type(None), Enum)
25
+ _SIMPLE_TYPE = (str, bytes, bytearray, int, float, type(None), _Enum)
26
26
 
27
27
 
28
- class EventStatus(str, ln.Enum):
28
+ class EventStatus(str, ln.types.Enum):
29
29
  """Status states for tracking action execution progress.
30
30
 
31
31
  Attributes:
@@ -96,7 +96,7 @@ class Execution:
96
96
  Returns:
97
97
  dict: A dictionary representation of the execution state.
98
98
  """
99
- res_ = ln.Unset
99
+ res_ = Unset
100
100
  json_serializable = True
101
101
 
102
102
  if not isinstance(self.response, _SIMPLE_TYPE):
@@ -119,7 +119,7 @@ class Execution:
119
119
  res_ = d_
120
120
  json_serializable = True
121
121
 
122
- if res_ is ln.Unset and not json_serializable:
122
+ if res_ is Unset and not json_serializable:
123
123
  res_ = "<unserializable>"
124
124
 
125
125
  return {
@@ -5,7 +5,11 @@
5
5
  import asyncio
6
6
  from typing import Any, ClassVar
7
7
 
8
- from lionagi.ln import ConcurrencyEvent, Semaphore, create_task_group
8
+ from lionagi.ln.concurrency import (
9
+ ConcurrencyEvent,
10
+ Semaphore,
11
+ create_task_group,
12
+ )
9
13
 
10
14
  from .._concepts import Observer
11
15
  from .element import ID
@@ -166,9 +170,9 @@ class Processor(Observer):
166
170
  async with self._concurrency_sem:
167
171
  await consume_stream(event)
168
172
 
169
- await tg.start_soon(stream_with_sem, next_event)
173
+ tg.start_soon(stream_with_sem, next_event)
170
174
  else:
171
- await tg.start_soon(consume_stream, next_event)
175
+ tg.start_soon(consume_stream, next_event)
172
176
  else:
173
177
  # For non-streaming, just invoke
174
178
  if self._concurrency_sem:
@@ -177,9 +181,9 @@ class Processor(Observer):
177
181
  async with self._concurrency_sem:
178
182
  await event.invoke()
179
183
 
180
- await tg.start_soon(invoke_with_sem, next_event)
184
+ tg.start_soon(invoke_with_sem, next_event)
181
185
  else:
182
- await tg.start_soon(next_event.invoke)
186
+ tg.start_soon(next_event.invoke)
183
187
  events_processed += 1
184
188
 
185
189
  prev_event = next_event
@@ -0,0 +1,82 @@
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """ID bridge utilities for V0/V1 compatibility.
6
+
7
+ This module provides utilities to convert between V0's IDType and V1's
8
+ canonical UUID representation, enabling seamless interoperability during
9
+ the gradual evolution process.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from typing import Any
15
+ from uuid import UUID
16
+
17
+ from .generic.element import Element, IDType
18
+
19
+ __all__ = (
20
+ "to_uuid",
21
+ "canonical_id",
22
+ )
23
+
24
+
25
+ def to_uuid(value: Any) -> UUID:
26
+ """Convert ID-like values (IDType | UUID | str | Element) to UUID (v4).
27
+
28
+ Optimized version that avoids string conversion when possible by directly
29
+ accessing IDType's internal UUID. Falls back to V0's IDType.validate()
30
+ for validation semantics only when necessary.
31
+
32
+ Args:
33
+ value: An ID-like value to convert (IDType, UUID, str, or Element)
34
+
35
+ Returns:
36
+ UUID: A validated UUIDv4
37
+
38
+ Raises:
39
+ IDError: If the value cannot be converted to a valid UUIDv4
40
+
41
+ Examples:
42
+ >>> element = Element()
43
+ >>> uuid_val = to_uuid(element)
44
+ >>> isinstance(uuid_val, UUID)
45
+ True
46
+ >>> to_uuid("550e8400-e29b-41d4-a716-446655440000")
47
+ UUID('550e8400-e29b-41d4-a716-446655440000')
48
+ """
49
+ if isinstance(value, Element):
50
+ return value.id._id
51
+ if isinstance(value, UUID):
52
+ return value
53
+ if hasattr(value, "_id") and isinstance(value._id, UUID):
54
+ return value._id
55
+ # Fallback: Validate then access ._id directly (no string conversion)
56
+ validated_id = IDType.validate(value)
57
+ return validated_id._id
58
+
59
+
60
+ def canonical_id(obj: Any) -> UUID:
61
+ """Accept an Observable-like object or raw ID and return canonical UUID.
62
+
63
+ Safe to use across V0/V1 without changing class definitions. Prefers
64
+ attribute access (.id) but falls back to treating the object as a raw ID.
65
+
66
+ Args:
67
+ obj: An Observable object with .id attribute, or a raw ID value
68
+
69
+ Returns:
70
+ UUID: The canonical UUID representation
71
+
72
+ Examples:
73
+ >>> element = Element()
74
+ >>> uuid_val = canonical_id(element)
75
+ >>> isinstance(uuid_val, UUID)
76
+ True
77
+ >>> canonical_id("550e8400-e29b-41d4-a716-446655440000")
78
+ UUID('550e8400-e29b-41d4-a716-446655440000')
79
+ """
80
+ # Prefer attribute access; fall back to treating obj as a raw id
81
+ id_like = getattr(obj, "id", obj)
82
+ return to_uuid(id_like)
@@ -2,18 +2,11 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
- from ._concepts import (
6
- Collective,
7
- Communicatable,
8
- Condition,
9
- Manager,
10
- Observable,
11
- Observer,
12
- Ordering,
13
- Relational,
14
- Sendable,
15
- )
5
+ from ._concepts import Collective, Communicatable, Condition, Manager
6
+ from ._concepts import Observable as LegacyObservable
7
+ from ._concepts import Observer, Ordering, Relational, Sendable
16
8
  from .action.manager import ActionManager, FunctionCalling, Tool, ToolRef
9
+ from .contracts import Observable, ObservableProto
17
10
  from .forms.flow import FlowDefinition, FlowStep
18
11
  from .forms.report import BaseForm, Form, Report
19
12
  from .generic.element import ID, Element, IDError, IDType, validate_order
@@ -30,6 +23,7 @@ from .generic.processor import Executor, Processor
30
23
  from .generic.progression import Progression, prog
31
24
  from .graph.edge import EdgeCondition
32
25
  from .graph.graph import Edge, Graph, Node
26
+ from .ids import canonical_id, to_uuid
33
27
  from .mail.exchange import Exchange, Mail, Mailbox, Package, PackageCategory
34
28
  from .mail.manager import MailManager
35
29
  from .messages.base import (
@@ -56,11 +50,15 @@ __all__ = (
56
50
  "Communicatable",
57
51
  "Condition",
58
52
  "Manager",
59
- "Observable",
53
+ "Observable", # V1 Protocol (preferred)
54
+ "ObservableProto", # Explicit V1 Protocol name
55
+ "LegacyObservable", # V0 ABC (deprecated)
60
56
  "Observer",
61
57
  "Ordering",
62
58
  "Relational",
63
59
  "Sendable",
60
+ "canonical_id", # V0/V1 bridge utility
61
+ "to_uuid", # ID conversion utility
64
62
  "ID",
65
63
  "Element",
66
64
  "IDError",
@@ -47,6 +47,15 @@ def match_endpoint(
47
47
  from .providers.perplexity_ import PerplexityChatEndpoint
48
48
 
49
49
  return PerplexityChatEndpoint(None, **kwargs)
50
+ if provider == "nvidia_nim":
51
+ if "embed" in endpoint:
52
+ from .providers.nvidia_nim_ import NvidiaNimEmbedEndpoint
53
+
54
+ return NvidiaNimEmbedEndpoint(None, **kwargs)
55
+ if "chat" in endpoint or "completion" in endpoint:
56
+ from .providers.nvidia_nim_ import NvidiaNimChatEndpoint
57
+
58
+ return NvidiaNimChatEndpoint(None, **kwargs)
50
59
  if provider == "claude_code":
51
60
  if "cli" in endpoint:
52
61
  from .providers.claude_code_cli import ClaudeCodeCLIEndpoint
@@ -0,0 +1,100 @@
1
+ # Copyright (c) 2025, HaiyangLi <quantocean.li at gmail dot com>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ NVIDIA NIM endpoint configurations.
7
+
8
+ This module provides endpoint configurations for NVIDIA NIM (NVIDIA Inference Microservices),
9
+ which offers GPU-accelerated inference for various AI models through an OpenAI-compatible API.
10
+
11
+ NVIDIA NIM features:
12
+ - OpenAI-compatible API endpoints
13
+ - GPU-accelerated inference
14
+ - Support for various open-source models (Llama, Mistral, etc.)
15
+ - Both cloud-hosted and self-hosted options
16
+ - Free tier with 1000 credits for development
17
+
18
+ API Documentation: https://docs.nvidia.com/nim/
19
+ Build Portal: https://build.nvidia.com/
20
+ """
21
+
22
+ from lionagi.config import settings
23
+ from lionagi.service.connections.endpoint import Endpoint
24
+ from lionagi.service.connections.endpoint_config import EndpointConfig
25
+
26
+ __all__ = (
27
+ "NvidiaNimChatEndpoint",
28
+ "NvidiaNimEmbedEndpoint",
29
+ "NVIDIA_NIM_CHAT_ENDPOINT_CONFIG",
30
+ "NVIDIA_NIM_EMBED_ENDPOINT_CONFIG",
31
+ )
32
+
33
+
34
+ def _get_nvidia_nim_config(**kwargs):
35
+ """Create NVIDIA NIM endpoint configuration with defaults.
36
+
37
+ NVIDIA NIM uses the integrate.api.nvidia.com endpoint for cloud-hosted models.
38
+ Authentication is via bearer token (API key from build.nvidia.com).
39
+ """
40
+ config = dict(
41
+ name="nvidia_nim_chat",
42
+ provider="nvidia_nim",
43
+ base_url="https://integrate.api.nvidia.com/v1",
44
+ endpoint="chat/completions",
45
+ kwargs={"model": "meta/llama3-8b-instruct"}, # Default model
46
+ api_key=settings.NVIDIA_NIM_API_KEY or "dummy-key-for-testing",
47
+ auth_type="bearer",
48
+ content_type="application/json",
49
+ method="POST",
50
+ requires_tokens=True,
51
+ # OpenAI-compatible format
52
+ )
53
+ config.update(kwargs)
54
+ return EndpointConfig(**config)
55
+
56
+
57
+ # Chat endpoint configuration
58
+ NVIDIA_NIM_CHAT_ENDPOINT_CONFIG = _get_nvidia_nim_config()
59
+
60
+ # Embedding endpoint configuration
61
+ # Note: You'll need to verify which embedding models are available on NVIDIA NIM
62
+ NVIDIA_NIM_EMBED_ENDPOINT_CONFIG = _get_nvidia_nim_config(
63
+ name="nvidia_nim_embed",
64
+ endpoint="embeddings",
65
+ kwargs={"model": "nvidia/nv-embed-v1"}, # Example embedding model
66
+ )
67
+
68
+
69
+ class NvidiaNimChatEndpoint(Endpoint):
70
+ """NVIDIA NIM chat completion endpoint.
71
+
72
+ Supports various open-source models including:
73
+ - meta/llama3-8b-instruct
74
+ - meta/llama3-70b-instruct
75
+ - meta/llama3.1-405b-instruct
76
+ - mistralai/mixtral-8x7b-instruct-v0.1
77
+ - google/gemma-7b
78
+ - And many more...
79
+
80
+ Get your API key from: https://build.nvidia.com/
81
+ """
82
+
83
+ def __init__(self, config=None, **kwargs):
84
+ config = config or _get_nvidia_nim_config()
85
+ super().__init__(config, **kwargs)
86
+
87
+
88
+ class NvidiaNimEmbedEndpoint(Endpoint):
89
+ """NVIDIA NIM embedding endpoint.
90
+
91
+ Note: Verify available embedding models at https://build.nvidia.com/
92
+ """
93
+
94
+ def __init__(self, config=None, **kwargs):
95
+ config = config or _get_nvidia_nim_config(
96
+ name="nvidia_nim_embed",
97
+ endpoint="embeddings",
98
+ kwargs={"model": "nvidia/nv-embed-v1"},
99
+ )
100
+ super().__init__(config, **kwargs)
lionagi/utils.py CHANGED
@@ -5,7 +5,6 @@
5
5
  import contextlib
6
6
  import copy as _copy
7
7
  import dataclasses
8
- import importlib.util
9
8
  import json
10
9
  import logging
11
10
  import types
@@ -37,11 +36,29 @@ from pydantic_core import PydanticUndefinedType
37
36
  from typing_extensions import deprecated
38
37
 
39
38
  from .libs.validate.xml_parser import xml_to_dict
40
- from .ln import DataClass, Enum, KeysDict, Params, Undefined, UndefinedType
41
- from .ln import extract_json as to_json
42
- from .ln import fuzzy_json as fuzzy_parse_json
43
- from .ln import hash_dict, to_list
44
- from .ln.concurrency import is_coro_func
39
+ from .ln import (
40
+ extract_json,
41
+ fuzzy_json,
42
+ get_bins,
43
+ hash_dict,
44
+ import_module,
45
+ is_coro_func,
46
+ is_import_installed,
47
+ to_list,
48
+ )
49
+ from .ln.types import (
50
+ DataClass,
51
+ Enum,
52
+ KeysDict,
53
+ MaybeSentinel,
54
+ MaybeUndefined,
55
+ MaybeUnset,
56
+ Params,
57
+ Undefined,
58
+ UndefinedType,
59
+ Unset,
60
+ UnsetType,
61
+ )
45
62
  from .settings import Settings
46
63
 
47
64
  R = TypeVar("R")
@@ -52,6 +69,9 @@ logger = logging.getLogger(__name__)
52
69
 
53
70
  UNDEFINED = Undefined
54
71
 
72
+ to_json = extract_json
73
+ fuzzy_parse_json = fuzzy_json
74
+
55
75
  __all__ = (
56
76
  "UndefinedType",
57
77
  "KeysDict",
@@ -76,7 +96,6 @@ __all__ = (
76
96
  "get_bins",
77
97
  "EventStatus",
78
98
  "logger",
79
- "throttle",
80
99
  "max_concurrent",
81
100
  "force_async",
82
101
  "breakdown_pydantic_annotation",
@@ -87,6 +106,14 @@ __all__ = (
87
106
  "is_union_type",
88
107
  "union_members",
89
108
  "to_json",
109
+ "Unset",
110
+ "UnsetType",
111
+ "Undefined",
112
+ "MaybeSentinel",
113
+ "MaybeUndefined",
114
+ "MaybeUnset",
115
+ "is_import_installed",
116
+ "import_module",
90
117
  )
91
118
 
92
119
 
@@ -888,60 +915,3 @@ def _is_pydantic_model(x: Any) -> bool:
888
915
  return isclass(x) and issubclass(x, BaseModel)
889
916
  except TypeError:
890
917
  return False
891
-
892
-
893
- def import_module(
894
- package_name: str,
895
- module_name: str = None,
896
- import_name: str | list = None,
897
- ) -> Any:
898
- """
899
- Import a module by its path.
900
-
901
- Args:
902
- module_path: The path of the module to import.
903
-
904
- Returns:
905
- The imported module.
906
-
907
- Raises:
908
- ImportError: If the module cannot be imported.
909
- """
910
- try:
911
- full_import_path = (
912
- f"{package_name}.{module_name}" if module_name else package_name
913
- )
914
-
915
- if import_name:
916
- import_name = (
917
- [import_name]
918
- if not isinstance(import_name, list)
919
- else import_name
920
- )
921
- a = __import__(
922
- full_import_path,
923
- fromlist=import_name,
924
- )
925
- if len(import_name) == 1:
926
- return getattr(a, import_name[0])
927
- return [getattr(a, name) for name in import_name]
928
- else:
929
- return __import__(full_import_path)
930
-
931
- except ImportError as e:
932
- raise ImportError(
933
- f"Failed to import module {full_import_path}: {e}"
934
- ) from e
935
-
936
-
937
- def is_import_installed(package_name: str) -> bool:
938
- """
939
- Check if a package is installed.
940
-
941
- Args:
942
- package_name: The name of the package to check.
943
-
944
- Returns:
945
- bool: True if the package is installed, False otherwise.
946
- """
947
- return importlib.util.find_spec(package_name) is not None
lionagi/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.15.13"
1
+ __version__ = "0.16.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lionagi
3
- Version: 0.15.13
3
+ Version: 0.16.0
4
4
  Summary: An Intelligence Operating System.
5
5
  Author-email: HaiyangLi <quantocean.li@gmail.com>
6
6
  License: Apache License
@@ -223,12 +223,14 @@ Requires-Dist: aiocache>=0.12.0
223
223
  Requires-Dist: aiohttp>=3.11.0
224
224
  Requires-Dist: anyio>=4.7.0
225
225
  Requires-Dist: backoff>=2.0.0
226
+ Requires-Dist: exceptiongroup>=1.3.0
226
227
  Requires-Dist: jinja2>=3.0.0
227
228
  Requires-Dist: json-repair>=0.40.0
229
+ Requires-Dist: msgspec>=0.18.0
228
230
  Requires-Dist: pillow>=10.0.0
229
231
  Requires-Dist: psutil>=6.0.0
230
232
  Requires-Dist: pydantic-settings>=2.8.0
231
- Requires-Dist: pydapter[pandas]>=1.0.4
233
+ Requires-Dist: pydapter[pandas]>=1.0.5
232
234
  Requires-Dist: python-dotenv>=1.1.0
233
235
  Requires-Dist: tiktoken>=0.9.0
234
236
  Requires-Dist: toml>=0.8.0