lionagi 0.14.7__py3-none-any.whl → 0.14.9__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 (45) hide show
  1. lionagi/_errors.py +120 -11
  2. lionagi/_types.py +0 -6
  3. lionagi/config.py +3 -1
  4. lionagi/fields/instruct.py +0 -1
  5. lionagi/models/operable_model.py +8 -3
  6. lionagi/operations/flow.py +0 -1
  7. lionagi/protocols/generic/event.py +2 -0
  8. lionagi/protocols/generic/log.py +26 -10
  9. lionagi/protocols/operatives/step.py +1 -1
  10. lionagi/protocols/types.py +9 -1
  11. lionagi/service/__init__.py +22 -1
  12. lionagi/service/connections/api_calling.py +57 -2
  13. lionagi/service/connections/endpoint_config.py +1 -1
  14. lionagi/service/connections/header_factory.py +4 -2
  15. lionagi/service/connections/match_endpoint.py +10 -10
  16. lionagi/service/connections/providers/anthropic_.py +5 -2
  17. lionagi/service/connections/providers/claude_code_.py +13 -17
  18. lionagi/service/connections/providers/claude_code_cli.py +51 -16
  19. lionagi/service/connections/providers/exa_.py +5 -3
  20. lionagi/service/connections/providers/oai_.py +116 -81
  21. lionagi/service/connections/providers/ollama_.py +38 -18
  22. lionagi/service/connections/providers/perplexity_.py +36 -14
  23. lionagi/service/connections/providers/types.py +30 -0
  24. lionagi/service/hooks/__init__.py +25 -0
  25. lionagi/service/hooks/_types.py +52 -0
  26. lionagi/service/hooks/_utils.py +85 -0
  27. lionagi/service/hooks/hook_event.py +67 -0
  28. lionagi/service/hooks/hook_registry.py +221 -0
  29. lionagi/service/imodel.py +120 -34
  30. lionagi/service/third_party/claude_code.py +715 -0
  31. lionagi/service/third_party/openai_model_names.py +198 -0
  32. lionagi/service/third_party/pplx_models.py +16 -8
  33. lionagi/service/types.py +21 -0
  34. lionagi/session/branch.py +1 -4
  35. lionagi/tools/base.py +1 -3
  36. lionagi/utils.py +8 -2
  37. lionagi/version.py +1 -1
  38. {lionagi-0.14.7.dist-info → lionagi-0.14.9.dist-info}/METADATA +66 -25
  39. {lionagi-0.14.7.dist-info → lionagi-0.14.9.dist-info}/RECORD +41 -37
  40. lionagi/service/connections/providers/_claude_code/__init__.py +0 -3
  41. lionagi/service/connections/providers/_claude_code/models.py +0 -234
  42. lionagi/service/connections/providers/_claude_code/stream_cli.py +0 -359
  43. lionagi/service/third_party/openai_models.py +0 -18241
  44. {lionagi-0.14.7.dist-info → lionagi-0.14.9.dist-info}/WHEEL +0 -0
  45. {lionagi-0.14.7.dist-info → lionagi-0.14.9.dist-info}/licenses/LICENSE +0 -0
lionagi/_errors.py CHANGED
@@ -2,28 +2,137 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
+ from __future__ import annotations
6
+
7
+ from typing import Any, ClassVar
8
+
9
+ __all__ = (
10
+ "LionError",
11
+ "ValidationError",
12
+ "NotFoundError",
13
+ "ExistsError",
14
+ "ObservationError",
15
+ "ResourceError",
16
+ "RateLimitError",
17
+ "IDError",
18
+ "RelationError",
19
+ "OperationError",
20
+ "ExecutionError",
21
+ "ItemNotFoundError",
22
+ "ItemExistsError",
23
+ )
24
+
5
25
 
6
26
  class LionError(Exception):
7
- pass
27
+ default_message: ClassVar[str] = "LionAGI error"
28
+ default_status_code: ClassVar[int] = 500
29
+ __slots__ = ("message", "details", "status_code")
30
+
31
+ def __init__(
32
+ self,
33
+ message: str | None = None,
34
+ *,
35
+ details: dict[str, Any] | None = None,
36
+ status_code: int | None = None,
37
+ cause: Exception | None = None,
38
+ ):
39
+ super().__init__(message or self.default_message)
40
+ if cause:
41
+ self.__cause__ = cause # preserves traceback
42
+ self.message = message or self.default_message
43
+ self.details = details or {}
44
+ self.status_code = status_code or type(self).default_status_code
45
+
46
+ def to_dict(self, *, include_cause: bool = False) -> dict[str, Any]:
47
+ data = {
48
+ "error": self.__class__.__name__,
49
+ "message": self.message,
50
+ "status_code": self.status_code,
51
+ **({"details": self.details} if self.details else {}),
52
+ }
53
+ if include_cause and (cause := self.get_cause()):
54
+ data["cause"] = repr(cause)
55
+ return data
56
+
57
+ def get_cause(self) -> Exception | None:
58
+ """Get the cause of this error, if any."""
59
+ return self.__cause__ if hasattr(self, "__cause__") else None
60
+
61
+ @classmethod
62
+ def from_value(
63
+ cls,
64
+ value: Any,
65
+ *,
66
+ expected: str | None = None,
67
+ message: str | None = None,
68
+ cause: Exception | None = None,
69
+ **extra: Any,
70
+ ):
71
+ """Create a ValidationError from a value with optional expected type and message."""
72
+ details = {
73
+ "value": value,
74
+ "type": type(value).__name__,
75
+ **({"expected": expected} if expected else {}),
76
+ **extra,
77
+ }
78
+ return cls(message=message, details=details, cause=cause)
8
79
 
9
80
 
10
- class ItemNotFoundError(LionError):
11
- pass
81
+ class ValidationError(LionError):
82
+ """Exception raised when validation fails."""
12
83
 
84
+ default_message = "Validation failed"
85
+ default_status_code = 422
86
+ __slots__ = ()
13
87
 
14
- class ItemExistsError(LionError):
15
- pass
16
88
 
89
+ class NotFoundError(LionError):
90
+ """Exception raised when an item is not found."""
17
91
 
18
- class IDError(LionError):
19
- pass
92
+ default_message = "Item not found"
93
+ default_status_code = 404
94
+ __slots__ = ()
20
95
 
21
96
 
22
- class RelationError(LionError):
23
- pass
97
+ class ExistsError(LionError):
98
+ """Exception raised when an item already exists."""
99
+
100
+ default_message = "Item already exists"
101
+ default_status_code = 409
102
+ __slots__ = ()
103
+
104
+
105
+ class ObservationError(LionError):
106
+ """Exception raised when an observation fails."""
107
+
108
+ default_message = "Observation failed"
109
+ default_status_code = 500
110
+ __slots__ = ()
111
+
112
+
113
+ class ResourceError(LionError):
114
+ """Exception raised when resource access fails."""
115
+
116
+ default_message = "Resource error"
117
+ default_status_code = 429
118
+ __slots__ = ()
24
119
 
25
120
 
26
121
  class RateLimitError(LionError):
122
+ __slots__ = ("retry_after",) # one extra attr
123
+ default_message = "Rate limit exceeded"
124
+ default_status_code = 429
125
+
126
+ def __init__(self, retry_after: float, **kw):
127
+ super().__init__(**kw)
128
+ object.__setattr__(self, "retry_after", retry_after)
129
+
130
+
131
+ class IDError(LionError):
132
+ pass
133
+
134
+
135
+ class RelationError(LionError):
27
136
  pass
28
137
 
29
138
 
@@ -35,5 +144,5 @@ class ExecutionError(LionError):
35
144
  pass
36
145
 
37
146
 
38
- class ValidationError(LionError):
39
- pass
147
+ ItemNotFoundError = NotFoundError
148
+ ItemExistsError = ExistsError
lionagi/_types.py CHANGED
@@ -1,9 +1,3 @@
1
1
  from .fields import *
2
2
  from .models import *
3
- from .operations import (
4
- BrainstormOperation,
5
- ExpansionStrategy,
6
- Operation,
7
- PlanOperation,
8
- )
9
3
  from .protocols.types import *
lionagi/config.py CHANGED
@@ -63,12 +63,14 @@ class AppSettings(BaseSettings, frozen=True):
63
63
  GROQ_API_KEY: SecretStr | None = None
64
64
  ANTHROPIC_API_KEY: SecretStr | None = None
65
65
 
66
+ OPENAI_DEFAULT_MODEL: str = "gpt-4.1-mini"
67
+
66
68
  # defaults models
67
69
  LIONAGI_EMBEDDING_PROVIDER: str = "openai"
68
70
  LIONAGI_EMBEDDING_MODEL: str = "text-embedding-3-small"
69
71
 
70
72
  LIONAGI_CHAT_PROVIDER: str = "openai"
71
- LIONAGI_CHAT_MODEL: str = "gpt-4.1-nano"
73
+ LIONAGI_CHAT_MODEL: str = "gpt-4.1-mini"
72
74
 
73
75
  # default storage
74
76
  LIONAGI_AUTO_STORE_EVENT: bool = False
@@ -11,7 +11,6 @@ from lionagi.libs.validate.common_field_validators import (
11
11
  validate_nullable_jsonvalue_field,
12
12
  )
13
13
  from lionagi.models import FieldModel, HashableModel
14
- from lionagi.utils import to_num
15
14
 
16
15
  __all__ = (
17
16
  "Instruct",
@@ -263,7 +263,7 @@ class OperableModel(HashableModel):
263
263
  Dictionary mapping field names to FieldInfo objects,
264
264
  excluding the extra_fields field itself
265
265
  """
266
- a = {**self.model_fields, **self.extra_fields}
266
+ a = {**type(self).model_fields, **self.extra_fields}
267
267
  a.pop("extra_fields", None)
268
268
  a.pop("extra_field_models", None) # Exclude internal field tracking
269
269
  return a
@@ -358,7 +358,12 @@ class OperableModel(HashableModel):
358
358
  for k, v in kwargs.items():
359
359
  self.field_setattr(field_name, k, v)
360
360
  else:
361
- self.extra_fields[field_name] = Field(**kwargs)
361
+ _kwargs = {
362
+ k: v
363
+ for k, v in kwargs.items()
364
+ if k not in ("name", "annotation", "validator_kwargs")
365
+ }
366
+ self.extra_fields[field_name] = Field(**_kwargs)
362
367
 
363
368
  # Handle no explicit defined field
364
369
  if not field_obj and not kwargs:
@@ -478,7 +483,7 @@ class OperableModel(HashableModel):
478
483
  raise KeyError(f"Field {field_name} not found in object fields.")
479
484
 
480
485
  if str(attr).strip("s").lower() == "annotation":
481
- return self.model_fields[field_name].annotation
486
+ return type(self).model_fields[field_name].annotation
482
487
 
483
488
  field_obj = all_fields[field_name]
484
489
 
@@ -349,7 +349,6 @@ class DependencyAwareExecutor:
349
349
  and branch.metadata
350
350
  and branch.metadata.get("pending_context_inheritance")
351
351
  ):
352
-
353
352
  primary_dep_id = branch.metadata.get("inherit_from_operation")
354
353
  if primary_dep_id and primary_dep_id in self.results:
355
354
  # Find the primary dependency's branch
@@ -30,6 +30,8 @@ class EventStatus(str, Enum):
30
30
  PROCESSING = "processing"
31
31
  COMPLETED = "completed"
32
32
  FAILED = "failed"
33
+ CANCELLED = "cancelled"
34
+ ABORTED = "aborted"
33
35
 
34
36
 
35
37
  class Execution:
@@ -13,18 +13,19 @@ from pydantic import BaseModel, Field, PrivateAttr, field_validator
13
13
 
14
14
  from lionagi.utils import create_path, to_dict
15
15
 
16
- from .._concepts import Manager
17
16
  from .element import Element
18
17
  from .pile import Pile
19
18
 
20
19
  __all__ = (
20
+ "DataLoggerConfig",
21
21
  "LogManagerConfig",
22
22
  "Log",
23
+ "DataLogger",
23
24
  "LogManager",
24
25
  )
25
26
 
26
27
 
27
- class LogManagerConfig(BaseModel):
28
+ class DataLoggerConfig(BaseModel):
28
29
  persist_dir: str | Path = "./data/logs"
29
30
  subfolder: str | None = None
30
31
  file_prefix: str | None = None
@@ -101,7 +102,7 @@ class Log(Element):
101
102
  return cls(content=content)
102
103
 
103
104
 
104
- class LogManager(Manager):
105
+ class DataLogger:
105
106
  """
106
107
  Manages a collection of logs, optionally auto-dumping them
107
108
  to CSV or JSON when capacity is reached or at program exit.
@@ -111,7 +112,7 @@ class LogManager(Manager):
111
112
  self,
112
113
  *,
113
114
  logs: Any = None,
114
- _config: LogManagerConfig = None,
115
+ _config: DataLoggerConfig = None,
115
116
  **kwargs,
116
117
  ):
117
118
  """
@@ -128,7 +129,7 @@ class LogManager(Manager):
128
129
  clear_after_dump: Whether to clear logs after saving.
129
130
  """
130
131
  if _config is None:
131
- _config = LogManagerConfig(**kwargs)
132
+ _config = DataLoggerConfig(**kwargs)
132
133
 
133
134
  if isinstance(logs, dict):
134
135
  self.logs = Pile.from_dict(logs)
@@ -188,8 +189,15 @@ class LogManager(Manager):
188
189
  if do_clear:
189
190
  self.logs.clear()
190
191
  except Exception as e:
191
- logging.error(f"Failed to dump logs: {e}")
192
- raise
192
+ # Check if it's a JSON serialization error with complex objects
193
+ if "JSON serializable" in str(e):
194
+ logging.debug(f"Could not serialize logs to JSON: {e}")
195
+ # Don't raise for JSON serialization issues during dumps
196
+ if clear is not False:
197
+ self.logs.clear() # Still clear if requested
198
+ else:
199
+ logging.error(f"Failed to dump logs: {e}")
200
+ raise
193
201
 
194
202
  async def adump(
195
203
  self,
@@ -222,16 +230,24 @@ class LogManager(Manager):
222
230
  try:
223
231
  self.dump(clear=self._config.clear_after_dump)
224
232
  except Exception as e:
225
- logging.error(f"Failed to save logs on exit: {e}")
233
+ # Only log debug level for JSON serialization errors during exit
234
+ # These are non-critical and often occur with complex objects
235
+ if "JSON serializable" in str(e):
236
+ logging.debug(f"Could not serialize logs to JSON: {e}")
237
+ else:
238
+ logging.error(f"Failed to save logs on exit: {e}")
226
239
 
227
240
  @classmethod
228
241
  def from_config(
229
- cls, config: LogManagerConfig, logs: Any = None
230
- ) -> LogManager:
242
+ cls, config: DataLoggerConfig, logs: Any = None
243
+ ) -> DataLogger:
231
244
  """
232
245
  Construct a LogManager from a LogManagerConfig.
233
246
  """
234
247
  return cls(_config=config, logs=logs)
235
248
 
236
249
 
250
+ LogManagerConfig = DataLoggerConfig
251
+ LogManager = DataLogger
252
+
237
253
  # File: lionagi/protocols/generic/log.py
@@ -168,7 +168,7 @@ class Step:
168
168
  ACTION_REQUESTS_FIELD,
169
169
  ]
170
170
  )
171
- if "reason" in operative.response_model.model_fields:
171
+ if "reason" in type(operative.response_model).model_fields:
172
172
  field_models.extend([REASON_FIELD])
173
173
 
174
174
  operative = Step._create_response_type(
@@ -18,7 +18,13 @@ from .forms.flow import FlowDefinition, FlowStep
18
18
  from .forms.report import BaseForm, Form, Report
19
19
  from .generic.element import ID, Element, IDError, IDType, validate_order
20
20
  from .generic.event import Event, EventStatus, Execution
21
- from .generic.log import Log, LogManager, LogManagerConfig
21
+ from .generic.log import (
22
+ DataLogger,
23
+ DataLoggerConfig,
24
+ Log,
25
+ LogManager,
26
+ LogManagerConfig,
27
+ )
22
28
  from .generic.pile import Pile, to_list_type
23
29
  from .generic.processor import Executor, Processor
24
30
  from .generic.progression import Progression, prog
@@ -107,4 +113,6 @@ __all__ = (
107
113
  "FunctionCalling",
108
114
  "ToolRef",
109
115
  "MailManager",
116
+ "DataLogger",
117
+ "DataLoggerConfig",
110
118
  )
@@ -1 +1,22 @@
1
- from .types import *
1
+ from .connections.api_calling import APICalling
2
+ from .connections.endpoint import Endpoint, EndpointConfig
3
+ from .hooks import *
4
+ from .imodel import iModel
5
+ from .manager import iModelManager
6
+ from .rate_limited_processor import RateLimitedAPIExecutor
7
+ from .token_calculator import TokenCalculator
8
+
9
+ __all__ = (
10
+ "APICalling",
11
+ "Endpoint",
12
+ "EndpointConfig",
13
+ "RateLimitedAPIExecutor",
14
+ "TokenCalculator",
15
+ "iModel",
16
+ "iModelManager",
17
+ "HookEventTypes",
18
+ "HookDict",
19
+ "AssosiatedEventInfo",
20
+ "HookEvent",
21
+ "HookRegistry",
22
+ )
@@ -5,10 +5,13 @@
5
5
  import asyncio
6
6
  import logging
7
7
 
8
- from pydantic import Field, model_validator
8
+ from anyio import get_cancelled_exc_class
9
+ from pydantic import Field, PrivateAttr, model_validator
9
10
  from typing_extensions import Self
10
11
 
11
12
  from lionagi.protocols.generic.event import Event, EventStatus
13
+ from lionagi.protocols.types import Log
14
+ from lionagi.service.hooks import HookEvent, HookEventTypes, global_hook_logger
12
15
  from lionagi.service.token_calculator import TokenCalculator
13
16
 
14
17
  from .endpoint import Endpoint
@@ -51,6 +54,9 @@ class APICalling(Event):
51
54
  exclude=True,
52
55
  )
53
56
 
57
+ _pre_invoke_hook_event: HookEvent = PrivateAttr(None)
58
+ _post_invoke_hook_event: HookEvent = PrivateAttr(None)
59
+
54
60
  @model_validator(mode="after")
55
61
  def _validate_streaming(self) -> Self:
56
62
  """Validate streaming configuration and add token usage if requested."""
@@ -162,6 +168,13 @@ class APICalling(Event):
162
168
 
163
169
  try:
164
170
  self.execution.status = EventStatus.PROCESSING
171
+ if h_ev := self._pre_invoke_hook_event:
172
+ await h_ev.invoke()
173
+ if h_ev._should_exit:
174
+ raise h_ev._exit_cause or RuntimeError(
175
+ "Pre-invocation hook requested exit without a cause"
176
+ )
177
+ await global_hook_logger.alog(Log.create(h_ev))
165
178
 
166
179
  # Make the API call with skip_payload_creation=True since payload is already prepared
167
180
  response = await self.endpoint.call(
@@ -171,10 +184,18 @@ class APICalling(Event):
171
184
  extra_headers=self.headers if self.headers else None,
172
185
  )
173
186
 
187
+ if h_ev := self._post_invoke_hook_event:
188
+ await h_ev.invoke()
189
+ if h_ev._should_exit:
190
+ raise h_ev._exit_cause or RuntimeError(
191
+ "Post-invocation hook requested exit without a cause"
192
+ )
193
+ await global_hook_logger.alog(Log.create(h_ev))
194
+
174
195
  self.execution.response = response
175
196
  self.execution.status = EventStatus.COMPLETED
176
197
 
177
- except asyncio.CancelledError:
198
+ except get_cancelled_exc_class():
178
199
  self.execution.error = "API call cancelled"
179
200
  self.execution.status = EventStatus.FAILED
180
201
  raise
@@ -228,3 +249,37 @@ class APICalling(Event):
228
249
  def response(self):
229
250
  """Get the response from the execution."""
230
251
  return self.execution.response if self.execution else None
252
+
253
+ def create_pre_invoke_hook(
254
+ self,
255
+ hook_registry,
256
+ exit_hook: bool = None,
257
+ hook_timeout: float = 30.0,
258
+ hook_params: dict = None,
259
+ ):
260
+ h_ev = HookEvent(
261
+ hook_type=HookEventTypes.PreInvokation,
262
+ event_like=self,
263
+ registry=hook_registry,
264
+ exit=exit_hook,
265
+ timeout=hook_timeout,
266
+ params=hook_params or {},
267
+ )
268
+ self._pre_invoke_hook_event = h_ev
269
+
270
+ def create_post_invoke_hook(
271
+ self,
272
+ hook_registry,
273
+ exit_hook: bool = None,
274
+ hook_timeout: float = 30.0,
275
+ hook_params: dict = None,
276
+ ):
277
+ h_ev = HookEvent(
278
+ hook_type=HookEventTypes.PostInvokation,
279
+ event_like=self,
280
+ registry=hook_registry,
281
+ exit=exit_hook,
282
+ timeout=hook_timeout,
283
+ params=hook_params or {},
284
+ )
285
+ self._post_invoke_hook_event = h_ev
@@ -32,7 +32,7 @@ class EndpointConfig(BaseModel):
32
32
  endpoint_params: list[str] | None = None
33
33
  method: str = "POST"
34
34
  params: dict[str, str] = Field(default_factory=dict)
35
- content_type: str = "application/json"
35
+ content_type: str | None = "application/json"
36
36
  auth_type: AUTH_TYPES = "bearer"
37
37
  default_headers: dict = {}
38
38
  request_options: B | None = None
@@ -27,11 +27,13 @@ class HeaderFactory:
27
27
  @staticmethod
28
28
  def get_header(
29
29
  auth_type: AUTH_TYPES,
30
- content_type: str = "application/json",
30
+ content_type: str | None = "application/json",
31
31
  api_key: str | SecretStr | None = None,
32
32
  default_headers: dict[str, str] | None = None,
33
33
  ) -> dict[str, str]:
34
- dict_ = HeaderFactory.get_content_type_header(content_type)
34
+ dict_ = {}
35
+ if content_type is not None:
36
+ dict_ = HeaderFactory.get_content_type_header(content_type)
35
37
 
36
38
  if auth_type == "none":
37
39
  # No authentication needed
@@ -16,49 +16,49 @@ def match_endpoint(
16
16
  if "chat" in endpoint:
17
17
  from .providers.oai_ import OpenaiChatEndpoint
18
18
 
19
- return OpenaiChatEndpoint(**kwargs)
19
+ return OpenaiChatEndpoint(None, **kwargs)
20
20
  if "response" in endpoint:
21
21
  from .providers.oai_ import OpenaiResponseEndpoint
22
22
 
23
- return OpenaiResponseEndpoint(**kwargs)
23
+ return OpenaiResponseEndpoint(None, **kwargs)
24
24
  if provider == "openrouter" and "chat" in endpoint:
25
25
  from .providers.oai_ import OpenrouterChatEndpoint
26
26
 
27
- return OpenrouterChatEndpoint(**kwargs)
27
+ return OpenrouterChatEndpoint(None, **kwargs)
28
28
  if provider == "ollama" and "chat" in endpoint:
29
29
  from .providers.ollama_ import OllamaChatEndpoint
30
30
 
31
- return OllamaChatEndpoint(**kwargs)
31
+ return OllamaChatEndpoint(None, **kwargs)
32
32
  if provider == "exa" and "search" in endpoint:
33
33
  from .providers.exa_ import ExaSearchEndpoint
34
34
 
35
- return ExaSearchEndpoint(**kwargs)
35
+ return ExaSearchEndpoint(None, **kwargs)
36
36
  if provider == "anthropic" and (
37
37
  "messages" in endpoint or "chat" in endpoint
38
38
  ):
39
39
  from .providers.anthropic_ import AnthropicMessagesEndpoint
40
40
 
41
- return AnthropicMessagesEndpoint(**kwargs)
41
+ return AnthropicMessagesEndpoint(None, **kwargs)
42
42
  if provider == "groq" and "chat" in endpoint:
43
43
  from .providers.oai_ import GroqChatEndpoint
44
44
 
45
- return GroqChatEndpoint(**kwargs)
45
+ return GroqChatEndpoint(None, **kwargs)
46
46
  if provider == "perplexity" and "chat" in endpoint:
47
47
  from .providers.perplexity_ import PerplexityChatEndpoint
48
48
 
49
- return PerplexityChatEndpoint(**kwargs)
49
+ return PerplexityChatEndpoint(None, **kwargs)
50
50
  if provider == "claude_code":
51
51
  if "cli" in endpoint:
52
52
  from .providers.claude_code_cli import ClaudeCodeCLIEndpoint
53
53
 
54
- return ClaudeCodeCLIEndpoint(**kwargs)
54
+ return ClaudeCodeCLIEndpoint(None, **kwargs)
55
55
 
56
56
  if "query" in endpoint or "code" in endpoint:
57
57
  from lionagi.service.connections.providers.claude_code_ import (
58
58
  ClaudeCodeEndpoint,
59
59
  )
60
60
 
61
- return ClaudeCodeEndpoint(**kwargs)
61
+ return ClaudeCodeEndpoint(None, **kwargs)
62
62
 
63
63
  from .providers.oai_ import OpenaiChatEndpoint
64
64
 
@@ -9,7 +9,7 @@ from lionagi.service.connections.endpoint import Endpoint
9
9
  from lionagi.service.connections.endpoint_config import EndpointConfig
10
10
  from lionagi.service.third_party.anthropic_models import CreateMessageRequest
11
11
 
12
- ANTHROPIC_MESSAGES_ENDPOINT_CONFIG = EndpointConfig(
12
+ _get_config = lambda: EndpointConfig(
13
13
  name="anthropic_messages",
14
14
  provider="anthropic",
15
15
  base_url="https://api.anthropic.com/v1",
@@ -22,13 +22,16 @@ ANTHROPIC_MESSAGES_ENDPOINT_CONFIG = EndpointConfig(
22
22
  request_options=CreateMessageRequest,
23
23
  )
24
24
 
25
+ ANTHROPIC_MESSAGES_ENDPOINT_CONFIG = _get_config() # backward compatibility
26
+
25
27
 
26
28
  class AnthropicMessagesEndpoint(Endpoint):
27
29
  def __init__(
28
30
  self,
29
- config: EndpointConfig = ANTHROPIC_MESSAGES_ENDPOINT_CONFIG,
31
+ config: EndpointConfig = None,
30
32
  **kwargs,
31
33
  ):
34
+ config = config or _get_config()
32
35
  super().__init__(config, **kwargs)
33
36
 
34
37
  def create_payload(