krons 0.1.0__py3-none-any.whl → 0.2.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 (162) hide show
  1. krons/__init__.py +49 -0
  2. krons/agent/__init__.py +144 -0
  3. krons/agent/mcps/__init__.py +14 -0
  4. krons/agent/mcps/loader.py +287 -0
  5. krons/agent/mcps/wrapper.py +799 -0
  6. krons/agent/message/__init__.py +20 -0
  7. krons/agent/message/action.py +69 -0
  8. krons/agent/message/assistant.py +52 -0
  9. krons/agent/message/common.py +49 -0
  10. krons/agent/message/instruction.py +130 -0
  11. krons/agent/message/prepare_msg.py +187 -0
  12. krons/agent/message/role.py +53 -0
  13. krons/agent/message/system.py +53 -0
  14. krons/agent/operations/__init__.py +82 -0
  15. krons/agent/operations/act.py +100 -0
  16. krons/agent/operations/generate.py +145 -0
  17. krons/agent/operations/llm_reparse.py +89 -0
  18. krons/agent/operations/operate.py +247 -0
  19. krons/agent/operations/parse.py +243 -0
  20. krons/agent/operations/react.py +286 -0
  21. krons/agent/operations/specs.py +235 -0
  22. krons/agent/operations/structure.py +151 -0
  23. krons/agent/operations/utils.py +79 -0
  24. krons/agent/providers/__init__.py +17 -0
  25. krons/agent/providers/anthropic_messages.py +146 -0
  26. krons/agent/providers/claude_code.py +276 -0
  27. krons/agent/providers/gemini.py +268 -0
  28. krons/agent/providers/match.py +75 -0
  29. krons/agent/providers/oai_chat.py +174 -0
  30. krons/agent/third_party/__init__.py +2 -0
  31. krons/agent/third_party/anthropic_models.py +154 -0
  32. krons/agent/third_party/claude_code.py +682 -0
  33. krons/agent/third_party/gemini_models.py +508 -0
  34. krons/agent/third_party/openai_models.py +295 -0
  35. krons/agent/tool.py +291 -0
  36. krons/core/__init__.py +127 -0
  37. krons/core/base/__init__.py +121 -0
  38. {kronos/core → krons/core/base}/broadcaster.py +7 -3
  39. {kronos/core → krons/core/base}/element.py +15 -7
  40. {kronos/core → krons/core/base}/event.py +41 -8
  41. {kronos/core → krons/core/base}/eventbus.py +4 -2
  42. {kronos/core → krons/core/base}/flow.py +14 -7
  43. {kronos/core → krons/core/base}/graph.py +27 -11
  44. {kronos/core → krons/core/base}/node.py +47 -22
  45. {kronos/core → krons/core/base}/pile.py +26 -12
  46. {kronos/core → krons/core/base}/processor.py +23 -9
  47. {kronos/core → krons/core/base}/progression.py +5 -3
  48. {kronos → krons/core}/specs/__init__.py +0 -5
  49. {kronos → krons/core}/specs/adapters/dataclass_field.py +16 -8
  50. {kronos → krons/core}/specs/adapters/pydantic_adapter.py +11 -5
  51. {kronos → krons/core}/specs/adapters/sql_ddl.py +16 -10
  52. {kronos → krons/core}/specs/catalog/__init__.py +2 -2
  53. {kronos → krons/core}/specs/catalog/_audit.py +3 -3
  54. {kronos → krons/core}/specs/catalog/_common.py +2 -2
  55. {kronos → krons/core}/specs/catalog/_content.py +5 -5
  56. {kronos → krons/core}/specs/catalog/_enforcement.py +4 -4
  57. {kronos → krons/core}/specs/factory.py +7 -7
  58. {kronos → krons/core}/specs/operable.py +9 -3
  59. {kronos → krons/core}/specs/protocol.py +4 -2
  60. {kronos → krons/core}/specs/spec.py +25 -13
  61. {kronos → krons/core}/types/base.py +7 -5
  62. {kronos → krons/core}/types/db_types.py +2 -2
  63. {kronos → krons/core}/types/identity.py +1 -1
  64. {kronos → krons}/errors.py +13 -13
  65. {kronos → krons}/protocols.py +9 -4
  66. krons/resource/__init__.py +89 -0
  67. {kronos/services → krons/resource}/backend.py +50 -24
  68. {kronos/services → krons/resource}/endpoint.py +28 -14
  69. {kronos/services → krons/resource}/hook.py +22 -9
  70. {kronos/services → krons/resource}/imodel.py +50 -32
  71. {kronos/services → krons/resource}/registry.py +27 -25
  72. {kronos/services → krons/resource}/utilities/rate_limited_executor.py +10 -6
  73. {kronos/services → krons/resource}/utilities/rate_limiter.py +4 -2
  74. {kronos/services → krons/resource}/utilities/resilience.py +17 -7
  75. krons/resource/utilities/token_calculator.py +185 -0
  76. {kronos → krons}/session/__init__.py +12 -17
  77. krons/session/constraints.py +70 -0
  78. {kronos → krons}/session/exchange.py +14 -6
  79. {kronos → krons}/session/message.py +4 -2
  80. krons/session/registry.py +35 -0
  81. {kronos → krons}/session/session.py +165 -174
  82. krons/utils/__init__.py +85 -0
  83. krons/utils/_function_arg_parser.py +99 -0
  84. krons/utils/_pythonic_function_call.py +249 -0
  85. {kronos → krons}/utils/_to_list.py +9 -3
  86. {kronos → krons}/utils/_utils.py +9 -5
  87. {kronos → krons}/utils/concurrency/__init__.py +38 -38
  88. {kronos → krons}/utils/concurrency/_async_call.py +6 -4
  89. {kronos → krons}/utils/concurrency/_errors.py +3 -1
  90. {kronos → krons}/utils/concurrency/_patterns.py +3 -1
  91. {kronos → krons}/utils/concurrency/_resource_tracker.py +6 -2
  92. krons/utils/display.py +257 -0
  93. {kronos → krons}/utils/fuzzy/__init__.py +6 -1
  94. {kronos → krons}/utils/fuzzy/_fuzzy_match.py +14 -8
  95. {kronos → krons}/utils/fuzzy/_string_similarity.py +3 -1
  96. {kronos → krons}/utils/fuzzy/_to_dict.py +3 -1
  97. krons/utils/schemas/__init__.py +26 -0
  98. krons/utils/schemas/_breakdown_pydantic_annotation.py +131 -0
  99. krons/utils/schemas/_formatter.py +72 -0
  100. krons/utils/schemas/_minimal_yaml.py +151 -0
  101. krons/utils/schemas/_typescript.py +153 -0
  102. {kronos → krons}/utils/sql/_sql_validation.py +1 -1
  103. krons/utils/validators/__init__.py +3 -0
  104. krons/utils/validators/_validate_image_url.py +56 -0
  105. krons/work/__init__.py +126 -0
  106. krons/work/engine.py +333 -0
  107. krons/work/form.py +305 -0
  108. {kronos → krons/work}/operations/__init__.py +7 -4
  109. {kronos → krons/work}/operations/builder.py +4 -4
  110. {kronos/enforcement → krons/work/operations}/context.py +37 -6
  111. {kronos → krons/work}/operations/flow.py +17 -9
  112. krons/work/operations/node.py +103 -0
  113. krons/work/operations/registry.py +103 -0
  114. {kronos/specs → krons/work}/phrase.py +131 -14
  115. {kronos/enforcement → krons/work}/policy.py +3 -3
  116. krons/work/report.py +268 -0
  117. krons/work/rules/__init__.py +47 -0
  118. {kronos/enforcement → krons/work/rules}/common/boolean.py +3 -1
  119. {kronos/enforcement → krons/work/rules}/common/choice.py +9 -3
  120. {kronos/enforcement → krons/work/rules}/common/number.py +3 -1
  121. {kronos/enforcement → krons/work/rules}/common/string.py +9 -3
  122. {kronos/enforcement → krons/work/rules}/rule.py +2 -2
  123. {kronos/enforcement → krons/work/rules}/validator.py +21 -6
  124. {kronos/enforcement → krons/work}/service.py +16 -7
  125. krons/work/worker.py +266 -0
  126. {krons-0.1.0.dist-info → krons-0.2.0.dist-info}/METADATA +19 -5
  127. krons-0.2.0.dist-info/RECORD +154 -0
  128. kronos/core/__init__.py +0 -145
  129. kronos/enforcement/__init__.py +0 -57
  130. kronos/operations/node.py +0 -101
  131. kronos/operations/registry.py +0 -92
  132. kronos/services/__init__.py +0 -81
  133. kronos/specs/adapters/__init__.py +0 -0
  134. kronos/utils/__init__.py +0 -40
  135. krons-0.1.0.dist-info/RECORD +0 -101
  136. {kronos → krons/core/specs/adapters}/__init__.py +0 -0
  137. {kronos → krons/core}/specs/adapters/_utils.py +0 -0
  138. {kronos → krons/core}/specs/adapters/factory.py +0 -0
  139. {kronos → krons/core}/types/__init__.py +0 -0
  140. {kronos → krons/core}/types/_sentinel.py +0 -0
  141. {kronos → krons}/py.typed +0 -0
  142. {kronos/services → krons/resource}/utilities/__init__.py +0 -0
  143. {kronos/services → krons/resource}/utilities/header_factory.py +0 -0
  144. {kronos → krons}/utils/_hash.py +0 -0
  145. {kronos → krons}/utils/_json_dump.py +0 -0
  146. {kronos → krons}/utils/_lazy_init.py +0 -0
  147. {kronos → krons}/utils/_to_num.py +0 -0
  148. {kronos → krons}/utils/concurrency/_cancel.py +0 -0
  149. {kronos → krons}/utils/concurrency/_primitives.py +0 -0
  150. {kronos → krons}/utils/concurrency/_priority_queue.py +0 -0
  151. {kronos → krons}/utils/concurrency/_run_async.py +0 -0
  152. {kronos → krons}/utils/concurrency/_task.py +0 -0
  153. {kronos → krons}/utils/concurrency/_utils.py +0 -0
  154. {kronos → krons}/utils/fuzzy/_extract_json.py +0 -0
  155. {kronos → krons}/utils/fuzzy/_fuzzy_json.py +0 -0
  156. {kronos → krons}/utils/sql/__init__.py +0 -0
  157. {kronos/enforcement → krons/work/rules}/common/__init__.py +0 -0
  158. {kronos/enforcement → krons/work/rules}/common/mapping.py +0 -0
  159. {kronos/enforcement → krons/work/rules}/common/model.py +0 -0
  160. {kronos/enforcement → krons/work/rules}/registry.py +0 -0
  161. {krons-0.1.0.dist-info → krons-0.2.0.dist-info}/WHEEL +0 -0
  162. {krons-0.1.0.dist-info → krons-0.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -12,11 +12,11 @@ from uuid import UUID
12
12
  from pydantic import Field, PrivateAttr, field_serializer, field_validator
13
13
  from typing_extensions import override
14
14
 
15
- from kronos.errors import ExistsError, NotFoundError
16
- from kronos.protocols import Containable, Deserializable, Serializable, implements
17
- from kronos.types import Unset, UnsetType, is_unset
18
- from kronos.utils import extract_types, load_type_from_string, synchronized
19
- from kronos.utils.concurrency import Lock as AsyncLock
15
+ from krons.core.types import Unset, UnsetType, is_unset
16
+ from krons.errors import ExistsError, NotFoundError
17
+ from krons.protocols import Containable, Deserializable, Serializable, implements
18
+ from krons.utils import extract_types, load_type_from_string, synchronized
19
+ from krons.utils.concurrency import Lock as AsyncLock
20
20
 
21
21
  from .element import Element
22
22
  from .progression import Progression
@@ -59,7 +59,9 @@ class Pile(Element, Generic[T]):
59
59
  @property
60
60
  def progression(self) -> Progression:
61
61
  """Read-only copy of progression order."""
62
- return Progression(order=list(self._progression.order), name=self._progression.name)
62
+ return Progression(
63
+ order=list(self._progression.order), name=self._progression.name
64
+ )
63
65
 
64
66
  item_type: set[type] | None = Field(
65
67
  default=None,
@@ -104,7 +106,9 @@ class Pile(Element, Generic[T]):
104
106
  NotFoundError: If order contains UUID not in items
105
107
  TypeError: If item type validation fails
106
108
  """
107
- super().__init__(**{"item_type": item_type, "strict_type": strict_type, **kwargs})
109
+ super().__init__(
110
+ **{"item_type": item_type, "strict_type": strict_type, **kwargs}
111
+ )
108
112
 
109
113
  if items:
110
114
  for item in items:
@@ -128,10 +132,14 @@ class Pile(Element, Generic[T]):
128
132
  def to_dict(
129
133
  self,
130
134
  mode: Literal["python", "json", "db"] = "python",
131
- created_at_format: (Literal["datetime", "isoformat", "timestamp"] | UnsetType) = Unset,
135
+ created_at_format: (
136
+ Literal["datetime", "isoformat", "timestamp"] | UnsetType
137
+ ) = Unset,
132
138
  meta_key: str | UnsetType = Unset,
133
139
  item_meta_key: str | UnsetType = Unset,
134
- item_created_at_format: (Literal["datetime", "isoformat", "timestamp"] | UnsetType) = Unset,
140
+ item_created_at_format: (
141
+ Literal["datetime", "isoformat", "timestamp"] | UnsetType
142
+ ) = Unset,
135
143
  **kwargs: Any,
136
144
  ) -> dict[str, Any]:
137
145
  """Serialize pile with items in progression order.
@@ -350,7 +358,9 @@ class Pile(Element, Generic[T]):
350
358
  raise TypeError("Cannot mix int and UUID in list/tuple indexing")
351
359
  items = [self.get(uid) for uid in keys]
352
360
  else:
353
- raise TypeError(f"list/tuple must contain only int or UUID, got {type(first)}")
361
+ raise TypeError(
362
+ f"list/tuple must contain only int or UUID, got {type(first)}"
363
+ )
354
364
 
355
365
  return Pile(
356
366
  items=items,
@@ -530,7 +540,9 @@ class Pile(Element, Generic[T]):
530
540
  and item_type_data
531
541
  and isinstance(item_type_data[0], str)
532
542
  ):
533
- allowed_types = {load_type_from_string(type_str) for type_str in item_type_data}
543
+ allowed_types = {
544
+ load_type_from_string(type_str) for type_str in item_type_data
545
+ }
534
546
  else:
535
547
  allowed_types = extract_types(item_type_data)
536
548
 
@@ -549,7 +561,9 @@ class Pile(Element, Generic[T]):
549
561
  "(strict_type=True)"
550
562
  )
551
563
  else:
552
- if not any(issubclass(item_type_actual, t) for t in allowed_types):
564
+ if not any(
565
+ issubclass(item_type_actual, t) for t in allowed_types
566
+ ):
553
567
  raise TypeError(
554
568
  f"Item type {kron_class} is not a subclass of any allowed type {allowed_types}"
555
569
  )
@@ -6,8 +6,8 @@ from __future__ import annotations
6
6
  import math
7
7
  from typing import TYPE_CHECKING, Any, ClassVar, Self
8
8
 
9
- from kronos.errors import ConfigurationError, NotFoundError, QueueFullError
10
- from kronos.utils import concurrency
9
+ from krons.errors import ConfigurationError, NotFoundError, QueueFullError
10
+ from krons.utils import concurrency
11
11
 
12
12
  from .event import Event, EventStatus
13
13
  from .flow import Flow
@@ -77,13 +77,19 @@ class Processor:
77
77
  if queue_capacity < 1:
78
78
  raise ValueError("Queue capacity must be greater than 0.")
79
79
  if queue_capacity > 10000:
80
- raise ValueError("Queue capacity must be <= 10000 (prevent unbounded batches).")
80
+ raise ValueError(
81
+ "Queue capacity must be <= 10000 (prevent unbounded batches)."
82
+ )
81
83
 
82
84
  # Validate capacity_refresh_time (prevent hot loop or starvation)
83
85
  if capacity_refresh_time < 0.01:
84
- raise ValueError("Capacity refresh time must be >= 0.01s (prevent CPU hot loop).")
86
+ raise ValueError(
87
+ "Capacity refresh time must be >= 0.01s (prevent CPU hot loop)."
88
+ )
85
89
  if capacity_refresh_time > 3600:
86
- raise ValueError("Capacity refresh time must be <= 3600s (prevent starvation).")
90
+ raise ValueError(
91
+ "Capacity refresh time must be <= 3600s (prevent starvation)."
92
+ )
87
93
 
88
94
  # Validate concurrency_limit
89
95
  if concurrency_limit < 1:
@@ -105,7 +111,9 @@ class Processor:
105
111
  self.concurrency_limit = concurrency_limit
106
112
 
107
113
  # Priority queue: (priority, event_uuid) tuples, min-heap ordering
108
- self.queue: concurrency.PriorityQueue[tuple[float, UUID]] = concurrency.PriorityQueue()
114
+ self.queue: concurrency.PriorityQueue[tuple[float, UUID]] = (
115
+ concurrency.PriorityQueue()
116
+ )
109
117
 
110
118
  self._available_capacity = queue_capacity
111
119
  self._execution_mode = False
@@ -231,7 +239,9 @@ class Processor:
231
239
  self._denial_counts.pop(event_id, None)
232
240
 
233
241
  if self.executor:
234
- await self.executor._update_progression(next_event, EventStatus.PROCESSING)
242
+ await self.executor._update_progression(
243
+ next_event, EventStatus.PROCESSING
244
+ )
235
245
 
236
246
  if next_event.streaming:
237
247
 
@@ -255,7 +265,9 @@ class Processor:
255
265
  if self.executor:
256
266
  await self.executor._update_progression(event)
257
267
 
258
- tg.start_soon(self._with_semaphore, invoke_and_update(next_event))
268
+ tg.start_soon(
269
+ self._with_semaphore, invoke_and_update(next_event)
270
+ )
259
271
 
260
272
  events_processed += 1
261
273
  self._available_capacity -= 1
@@ -270,7 +282,9 @@ class Processor:
270
282
 
271
283
  if denial_count >= 3:
272
284
  if self.executor:
273
- await self.executor._update_progression(next_event, EventStatus.ABORTED)
285
+ await self.executor._update_progression(
286
+ next_event, EventStatus.ABORTED
287
+ )
274
288
  self._denial_counts.pop(event_id, None)
275
289
  else:
276
290
  backoff = denial_count * 1.0
@@ -9,8 +9,8 @@ from uuid import UUID
9
9
 
10
10
  from pydantic import Field, PrivateAttr, field_validator
11
11
 
12
- from kronos.errors import NotFoundError
13
- from kronos.protocols import Containable, implements
12
+ from krons.errors import NotFoundError
13
+ from krons.protocols import Containable, implements
14
14
 
15
15
  from .element import Element
16
16
 
@@ -177,7 +177,9 @@ class Progression(Element):
177
177
  """Set item(s) at index. Slice assignment requires list value."""
178
178
  if isinstance(index, slice):
179
179
  if not isinstance(value, list):
180
- raise TypeError(f"Cannot assign {type(value).__name__} to slice, expected list")
180
+ raise TypeError(
181
+ f"Cannot assign {type(value).__name__} to slice, expected list"
182
+ )
181
183
  new_uids = [self._coerce_id(v) for v in value]
182
184
  self.order[index] = new_uids
183
185
  self._rebuild_members()
@@ -4,7 +4,6 @@
4
4
  from .adapters.factory import AdapterType, get_adapter
5
5
  from .catalog import AuditSpecs, CommonSpecs, ContentSpecs
6
6
  from .operable import Operable
7
- from .phrase import CrudOperation, CrudPattern, Phrase, phrase
8
7
  from .protocol import SpecAdapter
9
8
  from .spec import CommonMeta, Spec
10
9
 
@@ -14,12 +13,8 @@ __all__ = (
14
13
  "CommonMeta",
15
14
  "CommonSpecs",
16
15
  "ContentSpecs",
17
- "CrudOperation",
18
- "CrudPattern",
19
16
  "Operable",
20
- "Phrase",
21
17
  "Spec",
22
18
  "SpecAdapter",
23
19
  "get_adapter",
24
- "phrase",
25
20
  )
@@ -17,14 +17,14 @@ from dataclasses import field as dc_field
17
17
  from dataclasses import fields
18
18
  from typing import TYPE_CHECKING, Any
19
19
 
20
- from kronos.types._sentinel import Unset, UnsetType, is_sentinel
20
+ from krons.core.types._sentinel import Unset, UnsetType, is_sentinel
21
21
 
22
22
  from ..protocol import SpecAdapter
23
23
  from ..spec import Spec
24
24
  from ._utils import resolve_annotation_to_base_types
25
25
 
26
26
  if TYPE_CHECKING:
27
- from kronos.types.base import DataClass, ModelConfig, Params
27
+ from krons.core.types.base import DataClass, ModelConfig, Params
28
28
 
29
29
  from ..operable import Operable
30
30
 
@@ -71,7 +71,9 @@ def _make_validator_method(validators: dict[str, list[Any]], is_frozen: bool) ->
71
71
  errors.append(ValueError(f"Validation failed for '{fname}': {e}"))
72
72
 
73
73
  if errors:
74
- raise ExceptionGroup(f"Field validation failed for {type(self).__name__}", errors)
74
+ raise ExceptionGroup(
75
+ f"Field validation failed for {type(self).__name__}", errors
76
+ )
75
77
 
76
78
  return _validate_with_field_validators
77
79
 
@@ -149,7 +151,7 @@ class DataClassSpecAdapter(SpecAdapter[dict[str, Any]]):
149
151
  Returns:
150
152
  Dynamically created dataclass with validators wired in
151
153
  """
152
- from kronos.types.base import DataClass, Params
154
+ from krons.core.types.base import DataClass, Params
153
155
 
154
156
  use_specs = op.get_specs(include=include, exclude=exclude)
155
157
 
@@ -176,7 +178,9 @@ class DataClassSpecAdapter(SpecAdapter[dict[str, Any]]):
176
178
  annotations[field_name] = spec.annotation
177
179
 
178
180
  if "default_factory" in field_kwargs:
179
- class_attrs[field_name] = dc_field(default_factory=field_kwargs["default_factory"])
181
+ class_attrs[field_name] = dc_field(
182
+ default_factory=field_kwargs["default_factory"]
183
+ )
180
184
  elif "default" in field_kwargs:
181
185
  class_attrs[field_name] = field_kwargs["default"]
182
186
 
@@ -221,15 +225,19 @@ class DataClassSpecAdapter(SpecAdapter[dict[str, Any]]):
221
225
  return instance.to_dict()
222
226
 
223
227
  @classmethod
224
- def extract_specs(cls, structure: type[Params] | type[DataClass]) -> tuple[Spec, ...]:
228
+ def extract_specs(
229
+ cls, structure: type[Params] | type[DataClass]
230
+ ) -> tuple[Spec, ...]:
225
231
  """Extract Specs from DataClass/Params, preserving defaults and type modifiers.
226
232
 
227
233
  Raises:
228
234
  TypeError: If structure is not a DataClass or Params subclass
229
235
  """
230
- from kronos.types.base import DataClass, Params
236
+ from krons.core.types.base import DataClass, Params
231
237
 
232
- if not isinstance(structure, type) or not issubclass(structure, (DataClass, Params)):
238
+ if not isinstance(structure, type) or not issubclass(
239
+ structure, (DataClass, Params)
240
+ ):
233
241
  raise TypeError(
234
242
  f"structure must be a DataClass or Params subclass, got {type(structure)}"
235
243
  )
@@ -20,15 +20,21 @@ from pydantic.fields import FieldInfo
20
20
  from pydantic_core import PydanticUndefined
21
21
  from pydantic_core._pydantic_core import PydanticUndefinedType
22
22
 
23
- from kronos.specs.protocol import SpecAdapter
24
- from kronos.specs.spec import Spec
25
- from kronos.types._sentinel import Unset, UnsetType, is_sentinel, is_unset, not_sentinel
26
- from kronos.types.db_types import FKMeta, VectorMeta
23
+ from krons.core.specs.protocol import SpecAdapter
24
+ from krons.core.specs.spec import Spec
25
+ from krons.core.types._sentinel import (
26
+ Unset,
27
+ UnsetType,
28
+ is_sentinel,
29
+ is_unset,
30
+ not_sentinel,
31
+ )
32
+ from krons.core.types.db_types import FKMeta, VectorMeta
27
33
 
28
34
  from ._utils import resolve_annotation_to_base_types
29
35
 
30
36
  if TYPE_CHECKING:
31
- from kronos.specs.operable import Operable
37
+ from krons.core.specs.operable import Operable
32
38
 
33
39
  __all__ = ("PydanticSpecAdapter",)
34
40
 
@@ -27,16 +27,22 @@ from enum import StrEnum
27
27
  from typing import TYPE_CHECKING, Annotated, Any, get_args, get_origin
28
28
  from uuid import UUID
29
29
 
30
- from kronos.types._sentinel import Unset, UnsetType, is_sentinel
31
- from kronos.types.db_types import FK, FKMeta, Vector, VectorMeta, extract_kron_db_meta
32
- from kronos.utils.sql import validate_identifier
30
+ from krons.core.types._sentinel import Unset, UnsetType, is_sentinel
31
+ from krons.core.types.db_types import (
32
+ FK,
33
+ FKMeta,
34
+ Vector,
35
+ VectorMeta,
36
+ extract_kron_db_meta,
37
+ )
38
+ from krons.utils.sql import validate_identifier
33
39
 
34
40
  from ..protocol import SpecAdapter
35
41
  from ._utils import resolve_annotation_to_base_types
36
42
 
37
43
  if TYPE_CHECKING:
38
- from kronos.specs.operable import Operable
39
- from kronos.specs.spec import Spec
44
+ from krons.core.specs.operable import Operable
45
+ from krons.core.specs.spec import Spec
40
46
 
41
47
  __all__ = (
42
48
  # Enums
@@ -414,9 +420,7 @@ class UniqueConstraintSpec:
414
420
  for col in self.columns:
415
421
  validate_identifier(col, "column name")
416
422
  cols = ", ".join(f'"{c}"' for c in self.columns)
417
- return (
418
- f'ALTER TABLE "{schema}"."{table_name}" ADD CONSTRAINT "{self.name}" UNIQUE ({cols});'
419
- )
423
+ return f'ALTER TABLE "{schema}"."{table_name}" ADD CONSTRAINT "{self.name}" UNIQUE ({cols});'
420
424
 
421
425
 
422
426
  @dataclass(frozen=True, slots=True)
@@ -468,7 +472,9 @@ class TableSpec:
468
472
  col_lines = col_separator.join(col_defs)
469
473
 
470
474
  exists_clause = "IF NOT EXISTS " if if_not_exists else ""
471
- return f"CREATE TABLE {exists_clause}{self.qualified_name} (\n {col_lines}\n);"
475
+ return (
476
+ f"CREATE TABLE {exists_clause}{self.qualified_name} (\n {col_lines}\n);"
477
+ )
472
478
 
473
479
  def to_full_ddl(self) -> list[str]:
474
480
  """Generate all DDL statements for this table.
@@ -672,7 +678,7 @@ class SchemaSpec:
672
678
  Returns:
673
679
  SchemaSpec with version hash computed from table definitions.
674
680
  """
675
- from kronos.utils import compute_hash
681
+ from krons.utils import compute_hash
676
682
 
677
683
  tables = [
678
684
  TableSpec.from_operable(op, name, schema=schema)
@@ -9,14 +9,14 @@ Pre-defined Specs for common database patterns:
9
9
  - **CommonSpecs**: name, slug, status, email, phone, tenant_id, settings
10
10
 
11
11
  Usage:
12
- from kronos.specs.catalog import ContentSpecs, AuditSpecs
12
+ from krons.core.specs.catalog import ContentSpecs, AuditSpecs
13
13
 
14
14
  content_specs = ContentSpecs.get_specs(dim=1536)
15
15
  audit_specs = AuditSpecs.get_specs(use_uuid=True)
16
16
  all_specs = content_specs + audit_specs
17
17
 
18
18
  For custom Specs, use the factories directly:
19
- from kronos.specs.factory import create_embedding_spec, create_content_spec
19
+ from krons.core.specs.factory import create_embedding_spec, create_content_spec
20
20
 
21
21
  my_embedding = create_embedding_spec("embedding", dim=1536)
22
22
  my_content = create_content_spec("payload", content_type=MyModel)
@@ -10,9 +10,9 @@ from uuid import UUID
10
10
 
11
11
  from pydantic import BaseModel, Field
12
12
 
13
- from kronos.specs.operable import Operable
14
- from kronos.specs.spec import Spec
15
- from kronos.utils import now_utc
13
+ from krons.core.specs.operable import Operable
14
+ from krons.core.specs.spec import Spec
15
+ from krons.utils import now_utc
16
16
 
17
17
 
18
18
  class AuditSpecs(BaseModel):
@@ -10,8 +10,8 @@ from uuid import UUID
10
10
 
11
11
  from pydantic import BaseModel
12
12
 
13
- from kronos.specs.operable import Operable
14
- from kronos.specs.spec import Spec
13
+ from krons.core.specs.operable import Operable
14
+ from krons.core.specs.spec import Spec
15
15
 
16
16
 
17
17
  class CommonSpecs(BaseModel):
@@ -11,11 +11,11 @@ from uuid import UUID, uuid4
11
11
 
12
12
  from pydantic import BaseModel, Field
13
13
 
14
- from kronos.specs.operable import Operable
15
- from kronos.specs.spec import Spec
16
- from kronos.types._sentinel import Unset, UnsetType
17
- from kronos.types.db_types import VectorMeta
18
- from kronos.utils import now_utc
14
+ from krons.core.specs.operable import Operable
15
+ from krons.core.specs.spec import Spec
16
+ from krons.core.types._sentinel import Unset, UnsetType
17
+ from krons.core.types.db_types import VectorMeta
18
+ from krons.utils import now_utc
19
19
 
20
20
 
21
21
  class ContentSpecs(BaseModel):
@@ -10,10 +10,10 @@ from typing import Any
10
10
 
11
11
  from pydantic import BaseModel, Field, field_validator
12
12
 
13
- from kronos.specs.operable import Operable
14
- from kronos.specs.spec import Spec
15
- from kronos.types.base import Enum
16
- from kronos.utils import now_utc
13
+ from krons.core.specs.operable import Operable
14
+ from krons.core.specs.spec import Spec
15
+ from krons.core.types.base import Enum
16
+ from krons.utils import now_utc
17
17
 
18
18
  __all__ = (
19
19
  "EnforcementLevel",
@@ -8,14 +8,14 @@ from __future__ import annotations
8
8
  from datetime import datetime
9
9
  from uuid import UUID, uuid4
10
10
 
11
- from kronos.specs.spec import Spec, not_sentinel
12
- from kronos.types import UnsetType
13
- from kronos.types._sentinel import Unset
14
- from kronos.types.base import is_sentinel
11
+ from krons.core.specs.spec import Spec, not_sentinel
12
+ from krons.core.types import UnsetType
13
+ from krons.core.types._sentinel import Unset
14
+ from krons.core.types.base import is_sentinel
15
15
 
16
16
 
17
17
  def create_datetime_spec(name: str, *, use_default: bool) -> Spec:
18
- from kronos.utils._utils import coerce_created_at, now_utc
18
+ from krons.utils._utils import coerce_created_at, now_utc
19
19
 
20
20
  return Spec(
21
21
  datetime,
@@ -26,7 +26,7 @@ def create_datetime_spec(name: str, *, use_default: bool) -> Spec:
26
26
 
27
27
 
28
28
  def create_uuid_spec(name: str, *, use_default: bool) -> Spec:
29
- from kronos.utils._utils import to_uuid
29
+ from krons.utils._utils import to_uuid
30
30
 
31
31
  return Spec(
32
32
  UUID,
@@ -74,7 +74,7 @@ def create_embedding_spec(
74
74
  return Spec(list[float], name=name, default_factory=list)
75
75
  return Spec(list[float], name=name)
76
76
 
77
- from kronos.specs.adapters.sql_ddl import Vector
77
+ from krons.core.specs.adapters.sql_ddl import Vector
78
78
 
79
79
  return Spec(Vector[dim], name=name)
80
80
 
@@ -6,8 +6,14 @@ from __future__ import annotations
6
6
  from dataclasses import dataclass
7
7
  from typing import TYPE_CHECKING, Any, Self
8
8
 
9
- from kronos.protocols import Allowable, Hashable, implements
10
- from kronos.types._sentinel import MaybeUnset, Unset, UnsetType, is_unset, not_sentinel
9
+ from krons.core.types._sentinel import (
10
+ MaybeUnset,
11
+ Unset,
12
+ UnsetType,
13
+ is_unset,
14
+ not_sentinel,
15
+ )
16
+ from krons.protocols import Allowable, Hashable, implements
11
17
 
12
18
  from .adapters.factory import AdapterType, get_adapter
13
19
  from .protocol import SpecAdapter
@@ -311,4 +317,4 @@ class Operable:
311
317
  Returns:
312
318
  Dict representation of the instance
313
319
  """
314
- return self.adapter.dump_instance(instance, self)
320
+ return self.adapter.dump_instance(instance)
@@ -24,7 +24,7 @@ from __future__ import annotations
24
24
  from abc import ABC, abstractmethod
25
25
  from typing import TYPE_CHECKING, Any, Generic, TypeVar
26
26
 
27
- from kronos.types._sentinel import Unset, UnsetType
27
+ from krons.core.types._sentinel import Unset, UnsetType
28
28
 
29
29
  if TYPE_CHECKING:
30
30
  from .operable import Operable
@@ -126,7 +126,9 @@ class SpecAdapter(ABC, Generic[F]):
126
126
  Raises:
127
127
  NotImplementedError: If adapter doesn't support instance creation
128
128
  """
129
- raise NotImplementedError(f"{cls.__name__} does not support instance validation")
129
+ raise NotImplementedError(
130
+ f"{cls.__name__} does not support instance validation"
131
+ )
130
132
 
131
133
  @classmethod
132
134
  def dump_instance(cls, instance: Any, **kwargs) -> dict[str, Any]:
@@ -11,16 +11,16 @@ from collections.abc import Callable
11
11
  from dataclasses import dataclass
12
12
  from typing import Annotated, Any, Self
13
13
 
14
- from kronos.protocols import Hashable, implements
15
- from kronos.types._sentinel import (
14
+ from krons.core.types._sentinel import (
16
15
  MaybeUndefined,
17
16
  Undefined,
18
17
  is_sentinel,
19
18
  is_undefined,
20
19
  not_sentinel,
21
20
  )
22
- from kronos.types.base import Enum, Meta
23
- from kronos.utils.concurrency import is_coro_func
21
+ from krons.core.types.base import Enum, Meta
22
+ from krons.protocols import Hashable, implements
23
+ from krons.utils.concurrency import is_coro_func
24
24
 
25
25
  # Global cache for annotated types with bounded size
26
26
  _MAX_CACHE_SIZE = int(os.environ.get("kron_FIELD_CACHE_SIZE", "10000"))
@@ -64,13 +64,17 @@ class CommonMeta(Enum):
64
64
  errors: list[Exception] = []
65
65
 
66
66
  if kw.get("default") and kw.get("default_factory"):
67
- errors.append(ValueError("Cannot provide both 'default' and 'default_factory'"))
67
+ errors.append(
68
+ ValueError("Cannot provide both 'default' and 'default_factory'")
69
+ )
68
70
  if (_df := kw.get("default_factory")) and not callable(_df):
69
71
  errors.append(ValueError("'default_factory' must be callable"))
70
72
  if _val := kw.get("validator"):
71
73
  _val = [_val] if not isinstance(_val, list) else _val
72
74
  if not all(callable(v) for v in _val):
73
- errors.append(ValueError("Validators must be a list of functions or a function"))
75
+ errors.append(
76
+ ValueError("Validators must be a list of functions or a function")
77
+ )
74
78
 
75
79
  if errors:
76
80
  raise ExceptionGroup("Metadata validation failed", errors)
@@ -81,7 +85,7 @@ class CommonMeta(Enum):
81
85
  ) -> tuple[Meta, ...]:
82
86
  """Prepare metadata tuple from args/kw. Validates no duplicates, constraints."""
83
87
  # Lazy import to avoid circular dependency
84
- from kronos.utils._to_list import to_list
88
+ from krons.utils._to_list import to_list
85
89
 
86
90
  seen_keys = set()
87
91
  metas = []
@@ -192,7 +196,9 @@ class Spec:
192
196
  or isinstance(base_type, types.UnionType)
193
197
  )
194
198
  if not is_valid_type:
195
- raise ValueError(f"base_type must be a type or type annotation, got {base_type}")
199
+ raise ValueError(
200
+ f"base_type must be a type or type annotation, got {base_type}"
201
+ )
196
202
 
197
203
  if kw.get("default_factory") and is_coro_func(kw["default_factory"]):
198
204
  import warnings
@@ -389,7 +395,9 @@ class Spec:
389
395
 
390
396
  return spec
391
397
 
392
- def with_validator(self, validator: Callable[..., Any] | list[Callable[..., Any]]) -> Self:
398
+ def with_validator(
399
+ self, validator: Callable[..., Any] | list[Callable[..., Any]]
400
+ ) -> Self:
393
401
  """Return new Spec with validator function(s) attached."""
394
402
  return self.with_updates(validator=validator)
395
403
 
@@ -407,7 +415,7 @@ class Spec:
407
415
  if not is_undefined(fk):
408
416
  from uuid import UUID
409
417
 
410
- from kronos.types.db_types import FKMeta
418
+ from krons.core.types.db_types import FKMeta
411
419
 
412
420
  t_ = Annotated[UUID, FKMeta(fk)] # type: ignore[valid-type]
413
421
  if self.is_listable:
@@ -431,7 +439,9 @@ class Spec:
431
439
  _annotated_cache.move_to_end(cache_key)
432
440
  return _annotated_cache[cache_key]
433
441
 
434
- actual_type = Any if is_sentinel(self.base_type, {"none"}) else self.base_type
442
+ actual_type = (
443
+ Any if is_sentinel(self.base_type, {"none"}) else self.base_type
444
+ )
435
445
  current_metadata = self.metadata
436
446
 
437
447
  # Resolve FK target (explicit or Observable base_type)
@@ -440,7 +450,7 @@ class Spec:
440
450
  if not is_undefined(resolved_fk):
441
451
  from uuid import UUID
442
452
 
443
- from kronos.types.db_types import FKMeta
453
+ from krons.core.types.db_types import FKMeta
444
454
 
445
455
  actual_type = UUID # FK fields are UUID references
446
456
  extra_annotations.append(FKMeta(resolved_fk))
@@ -475,7 +485,9 @@ class Spec:
475
485
  exclude = set()
476
486
  if exclude_common:
477
487
  exclude = exclude | set(CommonMeta.allowed())
478
- return {meta.key: meta.value for meta in self.metadata if meta.key not in exclude}
488
+ return {
489
+ meta.key: meta.value for meta in self.metadata if meta.key not in exclude
490
+ }
479
491
 
480
492
 
481
493
  def _is_observable(cls: type) -> bool: