krons 0.1.1__py3-none-any.whl → 0.2.1__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.
- krons/__init__.py +49 -0
- krons/agent/__init__.py +144 -0
- krons/agent/mcps/__init__.py +14 -0
- krons/agent/mcps/loader.py +287 -0
- krons/agent/mcps/wrapper.py +799 -0
- krons/agent/message/__init__.py +20 -0
- krons/agent/message/action.py +69 -0
- krons/agent/message/assistant.py +52 -0
- krons/agent/message/common.py +49 -0
- krons/agent/message/instruction.py +130 -0
- krons/agent/message/prepare_msg.py +187 -0
- krons/agent/message/role.py +53 -0
- krons/agent/message/system.py +53 -0
- krons/agent/operations/__init__.py +82 -0
- krons/agent/operations/act.py +100 -0
- krons/agent/operations/generate.py +145 -0
- krons/agent/operations/llm_reparse.py +89 -0
- krons/agent/operations/operate.py +247 -0
- krons/agent/operations/parse.py +243 -0
- krons/agent/operations/react.py +286 -0
- krons/agent/operations/specs.py +235 -0
- krons/agent/operations/structure.py +151 -0
- krons/agent/operations/utils.py +79 -0
- krons/agent/providers/__init__.py +17 -0
- krons/agent/providers/anthropic_messages.py +146 -0
- krons/agent/providers/claude_code.py +276 -0
- krons/agent/providers/gemini.py +268 -0
- krons/agent/providers/match.py +75 -0
- krons/agent/providers/oai_chat.py +174 -0
- krons/agent/third_party/__init__.py +2 -0
- krons/agent/third_party/anthropic_models.py +154 -0
- krons/agent/third_party/claude_code.py +682 -0
- krons/agent/third_party/gemini_models.py +508 -0
- krons/agent/third_party/openai_models.py +295 -0
- krons/agent/tool.py +291 -0
- krons/core/__init__.py +56 -74
- krons/core/base/__init__.py +121 -0
- krons/core/{broadcaster.py → base/broadcaster.py} +7 -3
- krons/core/{element.py → base/element.py} +13 -5
- krons/core/{event.py → base/event.py} +39 -6
- krons/core/{eventbus.py → base/eventbus.py} +3 -1
- krons/core/{flow.py → base/flow.py} +11 -4
- krons/core/{graph.py → base/graph.py} +24 -8
- krons/core/{node.py → base/node.py} +44 -19
- krons/core/{pile.py → base/pile.py} +22 -8
- krons/core/{processor.py → base/processor.py} +21 -7
- krons/core/{progression.py → base/progression.py} +3 -1
- krons/{specs → core/specs}/__init__.py +0 -5
- krons/{specs → core/specs}/adapters/dataclass_field.py +16 -8
- krons/{specs → core/specs}/adapters/pydantic_adapter.py +11 -5
- krons/{specs → core/specs}/adapters/sql_ddl.py +14 -8
- krons/{specs → core/specs}/catalog/__init__.py +2 -2
- krons/{specs → core/specs}/catalog/_audit.py +2 -2
- krons/{specs → core/specs}/catalog/_common.py +2 -2
- krons/{specs → core/specs}/catalog/_content.py +4 -4
- krons/{specs → core/specs}/catalog/_enforcement.py +3 -3
- krons/{specs → core/specs}/factory.py +5 -5
- krons/{specs → core/specs}/operable.py +8 -2
- krons/{specs → core/specs}/protocol.py +4 -2
- krons/{specs → core/specs}/spec.py +23 -11
- krons/{types → core/types}/base.py +4 -2
- krons/{types → core/types}/db_types.py +2 -2
- krons/errors.py +13 -13
- krons/protocols.py +9 -4
- krons/resource/__init__.py +89 -0
- krons/{services → resource}/backend.py +48 -22
- krons/{services → resource}/endpoint.py +28 -14
- krons/{services → resource}/hook.py +20 -7
- krons/{services → resource}/imodel.py +46 -28
- krons/{services → resource}/registry.py +26 -24
- krons/{services → resource}/utilities/rate_limited_executor.py +7 -3
- krons/{services → resource}/utilities/rate_limiter.py +3 -1
- krons/{services → resource}/utilities/resilience.py +15 -5
- krons/resource/utilities/token_calculator.py +185 -0
- krons/session/__init__.py +12 -17
- krons/session/constraints.py +70 -0
- krons/session/exchange.py +11 -3
- krons/session/message.py +3 -1
- krons/session/registry.py +35 -0
- krons/session/session.py +165 -174
- krons/utils/__init__.py +45 -0
- krons/utils/_function_arg_parser.py +99 -0
- krons/utils/_pythonic_function_call.py +249 -0
- krons/utils/_to_list.py +9 -3
- krons/utils/_utils.py +6 -2
- krons/utils/concurrency/_async_call.py +4 -2
- krons/utils/concurrency/_errors.py +3 -1
- krons/utils/concurrency/_patterns.py +3 -1
- krons/utils/concurrency/_resource_tracker.py +6 -2
- krons/utils/display.py +257 -0
- krons/utils/fuzzy/__init__.py +6 -1
- krons/utils/fuzzy/_fuzzy_match.py +14 -8
- krons/utils/fuzzy/_string_similarity.py +3 -1
- krons/utils/fuzzy/_to_dict.py +3 -1
- krons/utils/schemas/__init__.py +26 -0
- krons/utils/schemas/_breakdown_pydantic_annotation.py +131 -0
- krons/utils/schemas/_formatter.py +72 -0
- krons/utils/schemas/_minimal_yaml.py +151 -0
- krons/utils/schemas/_typescript.py +153 -0
- krons/utils/validators/__init__.py +3 -0
- krons/utils/validators/_validate_image_url.py +56 -0
- krons/work/__init__.py +115 -0
- krons/work/engine.py +333 -0
- krons/work/form.py +242 -0
- krons/{operations → work/operations}/__init__.py +7 -4
- krons/{operations → work/operations}/builder.py +1 -1
- krons/{enforcement → work/operations}/context.py +36 -5
- krons/{operations → work/operations}/flow.py +13 -5
- krons/{operations → work/operations}/node.py +45 -43
- krons/work/operations/registry.py +103 -0
- krons/work/report.py +268 -0
- krons/work/rules/__init__.py +47 -0
- krons/{enforcement → work/rules}/common/boolean.py +3 -1
- krons/{enforcement → work/rules}/common/choice.py +9 -3
- krons/{enforcement → work/rules}/common/number.py +3 -1
- krons/{enforcement → work/rules}/common/string.py +9 -3
- krons/{enforcement → work/rules}/rule.py +1 -1
- krons/{enforcement → work/rules}/validator.py +20 -5
- krons/work/worker.py +266 -0
- {krons-0.1.1.dist-info → krons-0.2.1.dist-info}/METADATA +15 -1
- krons-0.2.1.dist-info/RECORD +151 -0
- krons/enforcement/__init__.py +0 -57
- krons/enforcement/policy.py +0 -80
- krons/enforcement/service.py +0 -370
- krons/operations/registry.py +0 -92
- krons/services/__init__.py +0 -81
- krons/specs/phrase.py +0 -405
- krons-0.1.1.dist-info/RECORD +0 -101
- /krons/{specs → core/specs}/adapters/__init__.py +0 -0
- /krons/{specs → core/specs}/adapters/_utils.py +0 -0
- /krons/{specs → core/specs}/adapters/factory.py +0 -0
- /krons/{types → core/types}/__init__.py +0 -0
- /krons/{types → core/types}/_sentinel.py +0 -0
- /krons/{types → core/types}/identity.py +0 -0
- /krons/{services → resource}/utilities/__init__.py +0 -0
- /krons/{services → resource}/utilities/header_factory.py +0 -0
- /krons/{enforcement → work/rules}/common/__init__.py +0 -0
- /krons/{enforcement → work/rules}/common/mapping.py +0 -0
- /krons/{enforcement → work/rules}/common/model.py +0 -0
- /krons/{enforcement → work/rules}/registry.py +0 -0
- {krons-0.1.1.dist-info → krons-0.2.1.dist-info}/WHEEL +0 -0
- {krons-0.1.1.dist-info → krons-0.2.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Copyright (c) 2025 - 2026, HaiyangLi <quantocean.li at gmail dot com>
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
"""Rules module: validation rules with auto-correction support.
|
|
5
|
+
|
|
6
|
+
Core exports:
|
|
7
|
+
- Rule, RuleParams, RuleQualifier: Base rule classes
|
|
8
|
+
- ValidationError: Validation failure exception
|
|
9
|
+
- Validator: Spec-aware validation orchestrator
|
|
10
|
+
- RuleRegistry: Type-to-rule mapping with inheritance
|
|
11
|
+
- Common rules: StringRule, NumberRule, BooleanRule, ChoiceRule, MappingRule, BaseModelRule
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from krons.errors import ValidationError
|
|
15
|
+
|
|
16
|
+
from .common import (
|
|
17
|
+
BaseModelRule,
|
|
18
|
+
BooleanRule,
|
|
19
|
+
ChoiceRule,
|
|
20
|
+
MappingRule,
|
|
21
|
+
NumberRule,
|
|
22
|
+
StringRule,
|
|
23
|
+
)
|
|
24
|
+
from .registry import RuleRegistry, get_default_registry, reset_default_registry
|
|
25
|
+
from .rule import Rule, RuleParams, RuleQualifier
|
|
26
|
+
from .validator import Validator
|
|
27
|
+
|
|
28
|
+
__all__ = (
|
|
29
|
+
# Base classes
|
|
30
|
+
"Rule",
|
|
31
|
+
"RuleParams",
|
|
32
|
+
"RuleQualifier",
|
|
33
|
+
"ValidationError",
|
|
34
|
+
# Validator
|
|
35
|
+
"Validator",
|
|
36
|
+
# Registry
|
|
37
|
+
"RuleRegistry",
|
|
38
|
+
"get_default_registry",
|
|
39
|
+
"reset_default_registry",
|
|
40
|
+
# Common rules
|
|
41
|
+
"BaseModelRule",
|
|
42
|
+
"BooleanRule",
|
|
43
|
+
"ChoiceRule",
|
|
44
|
+
"MappingRule",
|
|
45
|
+
"NumberRule",
|
|
46
|
+
"StringRule",
|
|
47
|
+
)
|
|
@@ -50,7 +50,9 @@ class BooleanRule(Rule):
|
|
|
50
50
|
ValueError: If not a boolean
|
|
51
51
|
"""
|
|
52
52
|
if not isinstance(v, bool):
|
|
53
|
-
raise ValueError(
|
|
53
|
+
raise ValueError(
|
|
54
|
+
f"Invalid boolean value: expected bool, got {type(v).__name__}"
|
|
55
|
+
)
|
|
54
56
|
|
|
55
57
|
async def perform_fix(self, v: Any, _t: type) -> Any:
|
|
56
58
|
"""Attempt to convert value to boolean.
|
|
@@ -58,7 +58,9 @@ class ChoiceRule(Rule):
|
|
|
58
58
|
self.case_sensitive = case_sensitive
|
|
59
59
|
|
|
60
60
|
if not case_sensitive:
|
|
61
|
-
self._lower_map = {
|
|
61
|
+
self._lower_map = {
|
|
62
|
+
str(c).lower(): c for c in self.choices if isinstance(c, str)
|
|
63
|
+
}
|
|
62
64
|
|
|
63
65
|
async def validate(self, v: Any, t: type, **kw) -> None:
|
|
64
66
|
"""Validate that value is in allowed choices (exact match only).
|
|
@@ -72,7 +74,9 @@ class ChoiceRule(Rule):
|
|
|
72
74
|
if v in self.choices:
|
|
73
75
|
return
|
|
74
76
|
|
|
75
|
-
raise ValueError(
|
|
77
|
+
raise ValueError(
|
|
78
|
+
f"Invalid choice: {v} not in {sorted(str(c) for c in self.choices)}"
|
|
79
|
+
)
|
|
76
80
|
|
|
77
81
|
async def perform_fix(self, v: Any, _t: type) -> Any:
|
|
78
82
|
"""Attempt to fix value to closest choice.
|
|
@@ -94,4 +98,6 @@ class ChoiceRule(Rule):
|
|
|
94
98
|
if v_lower in self._lower_map:
|
|
95
99
|
return self._lower_map[v_lower]
|
|
96
100
|
|
|
97
|
-
raise ValueError(
|
|
101
|
+
raise ValueError(
|
|
102
|
+
f"Cannot fix choice: {v} not in {sorted(str(c) for c in self.choices)}"
|
|
103
|
+
)
|
|
@@ -66,7 +66,9 @@ class NumberRule(Rule):
|
|
|
66
66
|
ValueError: If not a number or constraints violated
|
|
67
67
|
"""
|
|
68
68
|
if not isinstance(v, (int, float)):
|
|
69
|
-
raise ValueError(
|
|
69
|
+
raise ValueError(
|
|
70
|
+
f"Invalid number value: expected int or float, got {type(v).__name__}"
|
|
71
|
+
)
|
|
70
72
|
|
|
71
73
|
if self.ge is not None and v < self.ge:
|
|
72
74
|
raise ValueError(f"Number too small: {v} < {self.ge}")
|
|
@@ -103,14 +103,18 @@ class StringRule(Rule):
|
|
|
103
103
|
ValueError: If not a string or constraints violated
|
|
104
104
|
"""
|
|
105
105
|
if not isinstance(v, str):
|
|
106
|
-
raise ValueError(
|
|
106
|
+
raise ValueError(
|
|
107
|
+
f"Invalid string value: expected str, got {type(v).__name__}"
|
|
108
|
+
)
|
|
107
109
|
|
|
108
110
|
if self.min_length is not None and len(v) < self.min_length:
|
|
109
111
|
raise ValueError(
|
|
110
112
|
f"String too short: got {len(v)} characters, minimum {self.min_length}"
|
|
111
113
|
)
|
|
112
114
|
if self.max_length is not None and len(v) > self.max_length:
|
|
113
|
-
raise ValueError(
|
|
115
|
+
raise ValueError(
|
|
116
|
+
f"String too long: got {len(v)} characters, maximum {self.max_length}"
|
|
117
|
+
)
|
|
114
118
|
|
|
115
119
|
if self._compiled_pattern is not None:
|
|
116
120
|
if len(v) > self.regex_max_input_length:
|
|
@@ -119,7 +123,9 @@ class StringRule(Rule):
|
|
|
119
123
|
f"maximum {self.regex_max_input_length}"
|
|
120
124
|
)
|
|
121
125
|
if not self._compiled_pattern.match(v):
|
|
122
|
-
raise ValueError(
|
|
126
|
+
raise ValueError(
|
|
127
|
+
f"String does not match required pattern: {self.pattern}"
|
|
128
|
+
)
|
|
123
129
|
|
|
124
130
|
async def perform_fix(self, v: Any, t: type) -> Any:
|
|
125
131
|
"""Attempt to convert value to string and re-validate.
|
|
@@ -8,8 +8,8 @@ from dataclasses import dataclass, field
|
|
|
8
8
|
from enum import IntEnum, auto
|
|
9
9
|
from typing import Any
|
|
10
10
|
|
|
11
|
+
from krons.core.types import Params
|
|
11
12
|
from krons.errors import ValidationError
|
|
12
|
-
from krons.types import Params
|
|
13
13
|
|
|
14
14
|
__all__ = ("Rule", "RuleParams", "RuleQualifier", "ValidationError")
|
|
15
15
|
|
|
@@ -7,14 +7,16 @@ from collections import deque
|
|
|
7
7
|
from datetime import datetime
|
|
8
8
|
from typing import TYPE_CHECKING, Any, ClassVar
|
|
9
9
|
|
|
10
|
-
from krons.types import is_sentinel
|
|
10
|
+
from krons.core.types import is_sentinel, not_sentinel
|
|
11
11
|
from krons.utils.concurrency import is_coro_func
|
|
12
12
|
|
|
13
13
|
from .registry import RuleRegistry, get_default_registry
|
|
14
14
|
from .rule import Rule, ValidationError
|
|
15
15
|
|
|
16
16
|
if TYPE_CHECKING:
|
|
17
|
-
from
|
|
17
|
+
from pydantic import BaseModel
|
|
18
|
+
|
|
19
|
+
from krons.core.specs import Operable, Spec
|
|
18
20
|
|
|
19
21
|
__all__ = ("Validator",)
|
|
20
22
|
|
|
@@ -29,7 +31,9 @@ class Validator:
|
|
|
29
31
|
):
|
|
30
32
|
self.registry = registry or get_default_registry()
|
|
31
33
|
max_entries = (
|
|
32
|
-
max_log_entries
|
|
34
|
+
max_log_entries
|
|
35
|
+
if max_log_entries is not None
|
|
36
|
+
else self.DEFAULT_MAX_LOG_ENTRIES
|
|
33
37
|
)
|
|
34
38
|
self.validation_log: deque[dict[str, Any]] = deque(
|
|
35
39
|
maxlen=max_entries if max_entries > 0 else None
|
|
@@ -141,7 +145,9 @@ class Validator:
|
|
|
141
145
|
raise ValidationError(error_msg)
|
|
142
146
|
else:
|
|
143
147
|
try:
|
|
144
|
-
value = await rule.invoke(
|
|
148
|
+
value = await rule.invoke(
|
|
149
|
+
field_name, value, spec.base_type, auto_fix=auto_fix
|
|
150
|
+
)
|
|
145
151
|
except Exception as e:
|
|
146
152
|
self.log_validation_error(field_name, value, str(e))
|
|
147
153
|
raise
|
|
@@ -171,14 +177,20 @@ class Validator:
|
|
|
171
177
|
|
|
172
178
|
return value
|
|
173
179
|
|
|
174
|
-
async def
|
|
180
|
+
async def validate(
|
|
175
181
|
self,
|
|
176
182
|
data: dict[str, Any],
|
|
177
183
|
operable: Operable,
|
|
178
184
|
capabilities: set[str] | None = None,
|
|
179
185
|
auto_fix: bool = True,
|
|
180
186
|
strict: bool = True,
|
|
187
|
+
structure: type[BaseModel] | None = None,
|
|
181
188
|
) -> dict[str, Any]:
|
|
189
|
+
if not_sentinel(capabilities, {"none"}) and not capabilities.issubset(
|
|
190
|
+
operable.allowed()
|
|
191
|
+
):
|
|
192
|
+
raise ValidationError("Capabilities exceed operable's allowed set")
|
|
193
|
+
|
|
182
194
|
capabilities = capabilities or operable.allowed()
|
|
183
195
|
validated: dict[str, Any] = {}
|
|
184
196
|
|
|
@@ -195,4 +207,7 @@ class Validator:
|
|
|
195
207
|
spec, value, auto_fix=auto_fix, strict=strict
|
|
196
208
|
)
|
|
197
209
|
|
|
210
|
+
if structure is not None:
|
|
211
|
+
validated = operable.validate_instance(structure, validated)
|
|
212
|
+
|
|
198
213
|
return validated
|
krons/work/worker.py
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# Copyright (c) 2025 - 2026, HaiyangLi <quantocean.li at gmail dot com>
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
"""Worker - Declarative workflow definition via decorated methods.
|
|
5
|
+
|
|
6
|
+
A Worker defines workflows through:
|
|
7
|
+
- @work: Typed operations with assignment DSL (inputs -> outputs)
|
|
8
|
+
- @worklink: Conditional edges between work methods
|
|
9
|
+
|
|
10
|
+
Example:
|
|
11
|
+
class FileCoder(Worker):
|
|
12
|
+
@work(assignment="instruction, context -> code", capacity=2)
|
|
13
|
+
async def write_code(self, form_id, **kwargs):
|
|
14
|
+
result = await llm.chat(**kwargs)
|
|
15
|
+
return form_id, result.code
|
|
16
|
+
|
|
17
|
+
@worklink(from_="write_code", to_="execute_code")
|
|
18
|
+
async def write_to_execute(self, from_result):
|
|
19
|
+
form_id, code = from_result
|
|
20
|
+
return {"form_id": form_id, "code": code}
|
|
21
|
+
|
|
22
|
+
engine = WorkerEngine(worker=FileCoder())
|
|
23
|
+
await engine.add_task(form=my_form, task_function="write_code")
|
|
24
|
+
await engine.execute()
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from __future__ import annotations
|
|
28
|
+
|
|
29
|
+
import functools
|
|
30
|
+
from dataclasses import dataclass
|
|
31
|
+
from typing import TYPE_CHECKING, Awaitable, Callable
|
|
32
|
+
from uuid import UUID
|
|
33
|
+
|
|
34
|
+
if TYPE_CHECKING:
|
|
35
|
+
from .form import Form
|
|
36
|
+
|
|
37
|
+
__all__ = (
|
|
38
|
+
"Worker",
|
|
39
|
+
"WorkConfig",
|
|
40
|
+
"WorkLink",
|
|
41
|
+
"work",
|
|
42
|
+
"worklink",
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass
|
|
47
|
+
class WorkConfig:
|
|
48
|
+
"""Configuration for a @work decorated method.
|
|
49
|
+
|
|
50
|
+
Attributes:
|
|
51
|
+
assignment: DSL string 'inputs -> outputs' for typed I/O
|
|
52
|
+
form_param_key: Parameter name that receives form ID
|
|
53
|
+
capacity: Max concurrent executions (rate limiting)
|
|
54
|
+
refresh_time: Seconds between capacity resets
|
|
55
|
+
timeout: Max execution time in seconds
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
assignment: str = ""
|
|
59
|
+
form_param_key: str = ""
|
|
60
|
+
capacity: int = 1
|
|
61
|
+
refresh_time: float = 0.1
|
|
62
|
+
timeout: float | None = None
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@dataclass
|
|
66
|
+
class WorkLink:
|
|
67
|
+
"""Edge definition between work methods.
|
|
68
|
+
|
|
69
|
+
Attributes:
|
|
70
|
+
from_: Source method name
|
|
71
|
+
to_: Target method name
|
|
72
|
+
handler_name: Name of the handler method on the Worker
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
from_: str
|
|
76
|
+
to_: str
|
|
77
|
+
handler_name: str
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class Worker:
|
|
81
|
+
"""Base class for declarative workflow definition.
|
|
82
|
+
|
|
83
|
+
Subclass and decorate methods with @work and @worklink to define workflows.
|
|
84
|
+
Worker maintains form storage and tracks work method metadata.
|
|
85
|
+
|
|
86
|
+
Attributes:
|
|
87
|
+
name: Worker name (default: class name)
|
|
88
|
+
forms: Dict mapping form IDs to Form instances
|
|
89
|
+
_work_methods: Registry of @work decorated methods
|
|
90
|
+
_work_links: Registry of @worklink edges
|
|
91
|
+
_stopped: Stop flag for execution
|
|
92
|
+
|
|
93
|
+
Example:
|
|
94
|
+
class MyCoder(Worker):
|
|
95
|
+
name = "coder"
|
|
96
|
+
|
|
97
|
+
@work(assignment="task -> plan", capacity=2)
|
|
98
|
+
async def plan(self, task_name, **kwargs):
|
|
99
|
+
...
|
|
100
|
+
return task_name
|
|
101
|
+
|
|
102
|
+
@work(assignment="plan -> code", form_param_key="task_name")
|
|
103
|
+
async def implement(self, task_name, **kwargs):
|
|
104
|
+
...
|
|
105
|
+
|
|
106
|
+
@worklink(from_="plan", to_="implement")
|
|
107
|
+
async def plan_to_implement(self, from_result):
|
|
108
|
+
return {"task_name": from_result}
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
name: str = "worker"
|
|
112
|
+
|
|
113
|
+
def __init__(self) -> None:
|
|
114
|
+
"""Initialize worker state."""
|
|
115
|
+
# Form storage: form_id -> Form
|
|
116
|
+
self.forms: dict[str | UUID, Form] = {}
|
|
117
|
+
|
|
118
|
+
# Collect @work methods from class
|
|
119
|
+
self._work_methods: dict[str, tuple[Callable, WorkConfig]] = {}
|
|
120
|
+
self._work_links: list[WorkLink] = []
|
|
121
|
+
self._stopped = False
|
|
122
|
+
|
|
123
|
+
self._collect_work_metadata()
|
|
124
|
+
|
|
125
|
+
def _collect_work_metadata(self) -> None:
|
|
126
|
+
"""Scan class for @work and @worklink decorated methods."""
|
|
127
|
+
for name in dir(self):
|
|
128
|
+
if name.startswith("_"):
|
|
129
|
+
continue
|
|
130
|
+
|
|
131
|
+
attr = getattr(self, name, None)
|
|
132
|
+
if attr is None:
|
|
133
|
+
continue
|
|
134
|
+
|
|
135
|
+
# Check for @work decorator
|
|
136
|
+
if hasattr(attr, "_work_config"):
|
|
137
|
+
config: WorkConfig = attr._work_config
|
|
138
|
+
self._work_methods[name] = (attr, config)
|
|
139
|
+
|
|
140
|
+
# Check for @worklink decorator
|
|
141
|
+
if hasattr(attr, "_worklink_from") and hasattr(attr, "_worklink_to"):
|
|
142
|
+
link = WorkLink(
|
|
143
|
+
from_=attr._worklink_from,
|
|
144
|
+
to_=attr._worklink_to,
|
|
145
|
+
handler_name=name,
|
|
146
|
+
)
|
|
147
|
+
self._work_links.append(link)
|
|
148
|
+
|
|
149
|
+
def get_links_from(self, method_name: str) -> list[WorkLink]:
|
|
150
|
+
"""Get all outgoing links from a method."""
|
|
151
|
+
return [link for link in self._work_links if link.from_ == method_name]
|
|
152
|
+
|
|
153
|
+
def get_links_to(self, method_name: str) -> list[WorkLink]:
|
|
154
|
+
"""Get all incoming links to a method."""
|
|
155
|
+
return [link for link in self._work_links if link.to_ == method_name]
|
|
156
|
+
|
|
157
|
+
async def stop(self) -> None:
|
|
158
|
+
"""Signal worker to stop processing."""
|
|
159
|
+
self._stopped = True
|
|
160
|
+
|
|
161
|
+
async def start(self) -> None:
|
|
162
|
+
"""Clear stop flag to allow processing."""
|
|
163
|
+
self._stopped = False
|
|
164
|
+
|
|
165
|
+
def is_stopped(self) -> bool:
|
|
166
|
+
"""Check if worker is stopped."""
|
|
167
|
+
return self._stopped
|
|
168
|
+
|
|
169
|
+
def __repr__(self) -> str:
|
|
170
|
+
methods = list(self._work_methods.keys())
|
|
171
|
+
links = len(self._work_links)
|
|
172
|
+
forms = len(self.forms)
|
|
173
|
+
return f"{self.__class__.__name__}(methods={methods}, links={links}, forms={forms})"
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def work(
|
|
177
|
+
assignment: str = "",
|
|
178
|
+
*,
|
|
179
|
+
form_param_key: str = "",
|
|
180
|
+
capacity: int = 1,
|
|
181
|
+
refresh_time: float = 0.1,
|
|
182
|
+
timeout: float | None = None,
|
|
183
|
+
) -> Callable[[Callable[..., Awaitable]], Callable[..., Awaitable]]:
|
|
184
|
+
"""Decorator for typed work methods.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
assignment: DSL string 'inputs -> outputs' defining typed I/O.
|
|
188
|
+
Used for form field binding when form_param_key is set.
|
|
189
|
+
form_param_key: Parameter name that receives form ID.
|
|
190
|
+
If set, the engine will bind form fields to kwargs.
|
|
191
|
+
capacity: Max concurrent executions (for rate limiting).
|
|
192
|
+
refresh_time: Seconds between capacity resets.
|
|
193
|
+
timeout: Max execution time in seconds.
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
Decorator that attaches WorkConfig to the method.
|
|
197
|
+
|
|
198
|
+
Example:
|
|
199
|
+
@work(assignment="context, instruction -> code", form_param_key="form_id")
|
|
200
|
+
async def write_code(self, form_id, **kwargs):
|
|
201
|
+
# kwargs contains context, instruction from form
|
|
202
|
+
result = await llm.chat(**kwargs)
|
|
203
|
+
return form_id, result.code
|
|
204
|
+
"""
|
|
205
|
+
|
|
206
|
+
def decorator(func: Callable[..., Awaitable]) -> Callable[..., Awaitable]:
|
|
207
|
+
config = WorkConfig(
|
|
208
|
+
assignment=assignment,
|
|
209
|
+
form_param_key=form_param_key,
|
|
210
|
+
capacity=capacity,
|
|
211
|
+
refresh_time=refresh_time,
|
|
212
|
+
timeout=timeout,
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
@functools.wraps(func)
|
|
216
|
+
async def wrapper(*args, **kwargs):
|
|
217
|
+
return await func(*args, **kwargs)
|
|
218
|
+
|
|
219
|
+
wrapper._work_config = config # type: ignore[attr-defined]
|
|
220
|
+
return wrapper
|
|
221
|
+
|
|
222
|
+
return decorator
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def worklink(
|
|
226
|
+
from_: str,
|
|
227
|
+
to_: str,
|
|
228
|
+
) -> Callable[[Callable[..., Awaitable]], Callable[..., Awaitable]]:
|
|
229
|
+
"""Decorator for conditional edges between work methods.
|
|
230
|
+
|
|
231
|
+
The decorated function receives the result from the 'from_' method
|
|
232
|
+
and returns kwargs dict for the 'to_' method. Return None to skip
|
|
233
|
+
the edge (conditional routing).
|
|
234
|
+
|
|
235
|
+
Args:
|
|
236
|
+
from_: Source method name
|
|
237
|
+
to_: Target method name
|
|
238
|
+
|
|
239
|
+
Returns:
|
|
240
|
+
Decorator that attaches WorkLink info to the method.
|
|
241
|
+
|
|
242
|
+
Example:
|
|
243
|
+
@worklink(from_="write_code", to_="execute_code")
|
|
244
|
+
async def write_to_execute(self, from_result):
|
|
245
|
+
form_id, code = from_result
|
|
246
|
+
return {"form_id": form_id, "code": code}
|
|
247
|
+
|
|
248
|
+
@worklink(from_="execute_code", to_="debug_code")
|
|
249
|
+
async def execute_to_debug(self, from_result):
|
|
250
|
+
form_id, error = from_result
|
|
251
|
+
if error is not None: # Conditional edge
|
|
252
|
+
return {"form_id": form_id, "error": error}
|
|
253
|
+
# Return None = edge not taken
|
|
254
|
+
"""
|
|
255
|
+
|
|
256
|
+
def decorator(func: Callable[..., Awaitable]) -> Callable[..., Awaitable]:
|
|
257
|
+
@functools.wraps(func)
|
|
258
|
+
async def wrapper(*args, **kwargs):
|
|
259
|
+
return await func(*args, **kwargs)
|
|
260
|
+
|
|
261
|
+
# Store link info - handler_name will be set during _collect_work_metadata
|
|
262
|
+
wrapper._worklink_from = from_ # type: ignore[attr-defined]
|
|
263
|
+
wrapper._worklink_to = to_ # type: ignore[attr-defined]
|
|
264
|
+
return wrapper
|
|
265
|
+
|
|
266
|
+
return decorator
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: krons
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Spec-based composable framework for building type-safe systems
|
|
5
5
|
Project-URL: Homepage, https://github.com/khive-ai/krons
|
|
6
6
|
Project-URL: Repository, https://github.com/khive-ai/krons
|
|
@@ -22,7 +22,21 @@ Requires-Dist: anyio>=4.10.0
|
|
|
22
22
|
Requires-Dist: httpx>=0.26.0
|
|
23
23
|
Requires-Dist: orjson>=3.10.0
|
|
24
24
|
Requires-Dist: pydantic>=2.10.0
|
|
25
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
25
26
|
Requires-Dist: rapidfuzz>=3.10.0
|
|
27
|
+
Provides-Extra: agent
|
|
28
|
+
Requires-Dist: fastmcp>=2.14.4; extra == 'agent'
|
|
29
|
+
Requires-Dist: tiktoken>=0.11.0; extra == 'agent'
|
|
30
|
+
Provides-Extra: all
|
|
31
|
+
Requires-Dist: fastmcp>=2.14.4; extra == 'all'
|
|
32
|
+
Requires-Dist: rich>=13.0; extra == 'all'
|
|
33
|
+
Requires-Dist: tiktoken>=0.11.0; extra == 'all'
|
|
34
|
+
Provides-Extra: display
|
|
35
|
+
Requires-Dist: rich>=13.0; extra == 'display'
|
|
36
|
+
Provides-Extra: fastmcp
|
|
37
|
+
Requires-Dist: fastmcp>=2.14.4; extra == 'fastmcp'
|
|
38
|
+
Provides-Extra: tiktoken
|
|
39
|
+
Requires-Dist: tiktoken>=0.11.0; extra == 'tiktoken'
|
|
26
40
|
Description-Content-Type: text/markdown
|
|
27
41
|
|
|
28
42
|
# krons
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
krons/__init__.py,sha256=4q7g_NShAZ3SXLVTZ4H8vFSCXpps-3tjCs7qg6WkQPI,1359
|
|
2
|
+
krons/errors.py,sha256=nRWkWZmokOlp3hquC2dBe-gowdVIHllENiD0KxU3m8U,4051
|
|
3
|
+
krons/protocols.py,sha256=xYJUHdXbFHYtjy3rcEt8ttIngzigEve7tYa-8G35v7k,15333
|
|
4
|
+
krons/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
krons/agent/__init__.py,sha256=7AfP-1BHYosM5MiqcSOpoGF0y-bQ2OKN8oQePR2o98Y,4581
|
|
6
|
+
krons/agent/tool.py,sha256=JDlj_QCMw6ILKu2NkKLOoywiIlIIQwVfS-A_HT88OTg,8573
|
|
7
|
+
krons/agent/mcps/__init__.py,sha256=B3RYDI0XaDaECpgxqFp5bBIdCFRGPyzbCDpQeljY0P0,447
|
|
8
|
+
krons/agent/mcps/loader.py,sha256=SAw3ZLvBYHfT1bklLI7i15mnqwAA_aZtnJRR9WEfKl4,10554
|
|
9
|
+
krons/agent/mcps/wrapper.py,sha256=tW4aXzMMBqh4BtcuEaLxYqLxttGRJ06UQSjWmqdsGfI,28169
|
|
10
|
+
krons/agent/message/__init__.py,sha256=vumj0lHyraEoshw0tx8yWt5fyUUuAC3qVBiSLQuq-9A,499
|
|
11
|
+
krons/agent/message/action.py,sha256=ynONthCd78gWzl3dbQughJOGd-Iys6lbOzzYwuLXGWU,2047
|
|
12
|
+
krons/agent/message/assistant.py,sha256=V75490V9mQLKbBkH9cYAmnva2-Q3hwCAj_4flLUCvOE,1459
|
|
13
|
+
krons/agent/message/common.py,sha256=j9rpVoZhH6FV9JLVv6K-IgRJqPGnT5Vcw80UsEWv5ME,1282
|
|
14
|
+
krons/agent/message/instruction.py,sha256=jouxli_yDwRcLJhXs8f9cR0MdreW3pNRDIw2ha7K4uE,4793
|
|
15
|
+
krons/agent/message/prepare_msg.py,sha256=85XB-S2qxzXAUxn0cu46LNbWq0JL6w1IO1soJ3ci0Y4,7017
|
|
16
|
+
krons/agent/message/role.py,sha256=wKY5gIov4yHuvHiXEGFJ8YIaDR2YcmyH83JnDLgnFtI,1397
|
|
17
|
+
krons/agent/message/system.py,sha256=vCwFrYtM8K-5bVvl-mo0xW-Q_1AWqIAOgwDnNQ41DeA,1884
|
|
18
|
+
krons/agent/operations/__init__.py,sha256=UqKGE99xyYBGHnEHPVLq8Bf7dvs195gAnpMH3zpjNNA,2095
|
|
19
|
+
krons/agent/operations/act.py,sha256=WeUiVMcYOQN2EYLEvQU17HcqoQkcWzuqIgJjGP4AWXM,3606
|
|
20
|
+
krons/agent/operations/generate.py,sha256=oNXAwUKw3rcPlGkgq8zhggnNJPVcAzIIUhYIca23Ro0,5447
|
|
21
|
+
krons/agent/operations/llm_reparse.py,sha256=kF_KglZu_R4RVTpl-1lheeHGfvsK1bvAJidDdpW1iEA,2696
|
|
22
|
+
krons/agent/operations/operate.py,sha256=zOIPRoLYV0sXeSTmCvuD5mlwArimP456a7GEpxljjQ8,8966
|
|
23
|
+
krons/agent/operations/parse.py,sha256=HN7gnRm5_6gbabah3enaL280FVywQqIK5N6oOZG8NGQ,8261
|
|
24
|
+
krons/agent/operations/react.py,sha256=f5_5IVf8oi2TD8QXT53DefTxd1zO0nMmJ07SrL_28NQ,9468
|
|
25
|
+
krons/agent/operations/specs.py,sha256=UzH3A8VivQkUZdjDq78T_pmBQlY-BJafOVAKvpS0go8,7407
|
|
26
|
+
krons/agent/operations/structure.py,sha256=8HN5_dA4sYZFUbVPffEGmcamm9VUxFveAko59sgWydI,5250
|
|
27
|
+
krons/agent/operations/utils.py,sha256=goot2IAmrxTOoJa1kn2kfvv03i8mb02ifOKfBJMv_Qw,2335
|
|
28
|
+
krons/agent/providers/__init__.py,sha256=XJtszdh8f5sfAR0eQipKplBSLdKwtL0F7uQPmah8g6s,555
|
|
29
|
+
krons/agent/providers/anthropic_messages.py,sha256=x0oBKQa-T3zu8TyZ50Rm1fvgkY8ukzvAZJc1HVugBh0,4388
|
|
30
|
+
krons/agent/providers/claude_code.py,sha256=nTKJkK1gGUdCgXpzRXiGtC840a5qm0tKBeakqlPQ9Kw,9881
|
|
31
|
+
krons/agent/providers/gemini.py,sha256=TCJkk9iSnnkPdDuTlAB5yOphNYUPkPGKVYkrja9zcuI,9059
|
|
32
|
+
krons/agent/providers/match.py,sha256=3kiW-hyfnF6UgBYD7LG4KFhFKXbWpDdtDQ71-9t5wIQ,2251
|
|
33
|
+
krons/agent/providers/oai_chat.py,sha256=-97XBJ6WQT9OsjKSrV5s3or-WhBfUjDHomGiBYjCeVY,5463
|
|
34
|
+
krons/agent/third_party/__init__.py,sha256=gR454Rk5b1Bv3QibE-822UcoSWhpLCLtJae028QGtN4,110
|
|
35
|
+
krons/agent/third_party/anthropic_models.py,sha256=rd2Skh_Xx1S2G1JXi2YFb1j6SHm62e7brNBq9CZPAgI,3968
|
|
36
|
+
krons/agent/third_party/claude_code.py,sha256=NBYMsdPheb0PqGgTO2_aUAR2XoGDsPUwsB7Nd9PjipA,23758
|
|
37
|
+
krons/agent/third_party/gemini_models.py,sha256=2dag2WbSTKLBd8t0F7t_TXCcl7aqsTFgDI6XLkhsZwM,17416
|
|
38
|
+
krons/agent/third_party/openai_models.py,sha256=L-GkJ-bBW5zwPbgCWEYHMNqRiZfFTAUJE96AVZoDAkQ,8040
|
|
39
|
+
krons/core/__init__.py,sha256=HG0wBaNCbH3xGDRNX3657g-hZo4Isu2MKaXeUXmXqa0,3496
|
|
40
|
+
krons/core/base/__init__.py,sha256=Edl_HH2F1l0SMHMzuEPU_IFjkigRR1vtqVXcPm-mr1o,3614
|
|
41
|
+
krons/core/base/broadcaster.py,sha256=Es__WfL-j2h5NS6aU18fgaFkZsJIL-zDe86Qvlea-io,4013
|
|
42
|
+
krons/core/base/element.py,sha256=LqBbmPttXoDAFy56JzWhSJ4sBw_LW7hMGxZUog85N8g,7642
|
|
43
|
+
krons/core/base/event.py,sha256=iZQ65Xg3a8eaCEl4Hca-pxPNtckhrHkydEqYyppbuo0,11524
|
|
44
|
+
krons/core/base/eventbus.py,sha256=z45ORtGey5A1N9hdyEPOhlX1whaTTdqdk7g3XEDL-_8,3761
|
|
45
|
+
krons/core/base/flow.py,sha256=eqsYm8QO7bD5Y9VYnlpHFWpaUCY0rCeKGrDrFUyBVA4,12364
|
|
46
|
+
krons/core/base/graph.py,sha256=FiTMArxuz6At3oYPEoamES3FtBM-AM6QnA7EQ8G18mo,15972
|
|
47
|
+
krons/core/base/node.py,sha256=0_-R6uNe6-LF3adQRZowSIICdy6ep3cQIQRdF0oosoQ,34699
|
|
48
|
+
krons/core/base/pile.py,sha256=ZKvnX3BjMsrH989TLNZII1dDWv4yPhSRzLKXx2yzyKQ,21108
|
|
49
|
+
krons/core/base/processor.py,sha256=GrdNZa5YD0tXle847ttnxuWe4Ego1MhULzWHmSz5RqQ,18768
|
|
50
|
+
krons/core/base/progression.py,sha256=srcrmp_zALgg7II5TJsuMM9DdNJszgTxLxvES0WBOTE,9844
|
|
51
|
+
krons/core/specs/__init__.py,sha256=AKFEXqLmJpW__Y6xorJ1Vbp7AZ46kIs0157STVFGVWk,500
|
|
52
|
+
krons/core/specs/factory.py,sha256=TsRZIoWuz0sLYUGfQ_X5Gff2oBll-quk-kOnpX5_yB0,3362
|
|
53
|
+
krons/core/specs/operable.py,sha256=zO15i56_UzTTuM3yg_-EMtQY1Equ_WBi3rUCoCKrYck,11067
|
|
54
|
+
krons/core/specs/protocol.py,sha256=Se-Cow7de4hF4vkvw5qYj14c37JJ-4aJSDIvJHFyst8,4392
|
|
55
|
+
krons/core/specs/spec.py,sha256=QaVWN3ZrX8l1x15xXtfpNGzSIV01X0H3jy9Mjv9vT8Y,18706
|
|
56
|
+
krons/core/specs/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
57
|
+
krons/core/specs/adapters/_utils.py,sha256=ChWH-C2LRXaXiWM3n7P0DZ8Oci5dSDq59DIJtHx2h-g,1365
|
|
58
|
+
krons/core/specs/adapters/dataclass_field.py,sha256=thhgC3iQsrkfMkKzB4XmDbwh4fpLYocdL0KvY_zxbzo,8802
|
|
59
|
+
krons/core/specs/adapters/factory.py,sha256=_LoSMCtHNkK5kNL5LUDjHvJJ2BtDHAaW1gly5LpNPXQ,1572
|
|
60
|
+
krons/core/specs/adapters/pydantic_adapter.py,sha256=UxnOtJdeIyJEPBBjSACWE-JVc0yWxHSepz5i2SZhS6A,10410
|
|
61
|
+
krons/core/specs/adapters/sql_ddl.py,sha256=NTttvx16X926qeQNWxqdoLlToeiMwufpKEPWNdAXHg0,31377
|
|
62
|
+
krons/core/specs/catalog/__init__.py,sha256=TwS7hvGxa4-2Usu5rKGlhmUS0hhBlRzVNFNKDE7q8eU,1231
|
|
63
|
+
krons/core/specs/catalog/_audit.py,sha256=g-L4eSJw3H0hfejex5LwsnepaGyTUPrL8JbPU7lPycY,1260
|
|
64
|
+
krons/core/specs/catalog/_common.py,sha256=ItOPWV1fEeaz6ss5XNZYUetp204saIs7s5Bl0Jt8AOQ,1207
|
|
65
|
+
krons/core/specs/catalog/_content.py,sha256=pQAbgjoObZcAQLe8Wg-_sqQ8VYZUGsRQJnjuiCjH-p0,1972
|
|
66
|
+
krons/core/specs/catalog/_enforcement.py,sha256=JlKF_qGc-Xk7E_ebvq6lQs19iRBAWk2TOe1Qm7XMf1k,2126
|
|
67
|
+
krons/core/types/__init__.py,sha256=pJ6kuop7vSLZp5jMBs-CQ7CHRjvUuO8kHhpZ34KM85I,1049
|
|
68
|
+
krons/core/types/_sentinel.py,sha256=QJGyRAYNkJ2ylw6dhxPHJNgmxqBdorBd-xx7pNrUykw,8855
|
|
69
|
+
krons/core/types/base.py,sha256=Un3MrPGuyns9SgPczJ5vbQExemTO-9B2Eks87NDd--A,12330
|
|
70
|
+
krons/core/types/db_types.py,sha256=3ZaAXJe4dartmF-IyKr59NVlL2EbGpx7AtVqqbrIXIk,8136
|
|
71
|
+
krons/core/types/identity.py,sha256=Ccb5oJArC1PEzdzNPlLi_oK87uKx7BFevX9rvY9y-14,1949
|
|
72
|
+
krons/resource/__init__.py,sha256=h83vOSa6zXXMRdfxch7yg7kGy6Pe_6c0wWANByATbZ8,2783
|
|
73
|
+
krons/resource/backend.py,sha256=mW1kkAZrUwnBZeMOY_0I_egpTKpuNyIs5Mps4r2cOxk,10979
|
|
74
|
+
krons/resource/endpoint.py,sha256=X_Yt5KLXKN5Wwc75MX0c5gPyE_Dlv16rIfm8CKd1xYE,22253
|
|
75
|
+
krons/resource/hook.py,sha256=XQujjDwBZa2vCktP6Ey0QFfFFNEd6igc1qUR5-tfeQU,17115
|
|
76
|
+
krons/resource/imodel.py,sha256=_BOfbLk5JNoKAnjf3k67E6O2Qef4fsKa1hprw1C4L1Q,18595
|
|
77
|
+
krons/resource/registry.py,sha256=Vqe8uUtMMtxu4NgU5RUPFmpIxtKxdCfmVQQy1lhZMZo,3829
|
|
78
|
+
krons/resource/utilities/__init__.py,sha256=-ycdoYgtXrliJwbtQGMHBRvZL0qX2xLzooL3RNV99x4,1013
|
|
79
|
+
krons/resource/utilities/header_factory.py,sha256=WZCCZMh9EJVi8tnY7dJD07FcTOrrUMvecJmzy8P65Os,2992
|
|
80
|
+
krons/resource/utilities/rate_limited_executor.py,sha256=xtvxTeHowoghb4WpY_9WNgqbFKHPBZKtKbaGyaTpTsk,9710
|
|
81
|
+
krons/resource/utilities/rate_limiter.py,sha256=DdaqnxOnst43ZAxcC9kBnnFbUCAsR89KzA0XL5xGPtU,6003
|
|
82
|
+
krons/resource/utilities/resilience.py,sha256=eOPSZ6m89IH_RCgaGLrFPQGTZtMBZOrs8G0sjSpfv40,14389
|
|
83
|
+
krons/resource/utilities/token_calculator.py,sha256=gBQvkmqL4gnqFx5o-FtPeoLDPBFTdN0ZpFkaT71VVLk,6437
|
|
84
|
+
krons/session/__init__.py,sha256=aCdCYe2HCLV8ujlBZHSqFr0nF8gj_PypI0BXoIU7ThU,1017
|
|
85
|
+
krons/session/constraints.py,sha256=DvmLKyf5eYUX2nxCDcco1-uDipGjiIJwoUxWVtX2w84,2361
|
|
86
|
+
krons/session/exchange.py,sha256=QChEqK5NFZJpHWxPrXd8LkGBCFg6LNONd1ZEy0MufpI,9165
|
|
87
|
+
krons/session/message.py,sha256=mtZ-PYCCoyWLy7BSB5TL5a0hIt0aQX2zdckOCIl6NZ0,2007
|
|
88
|
+
krons/session/registry.py,sha256=13pPKmDZJaj9q27oUOdtH6-jrHP_HDFF8lCdcNF--EE,999
|
|
89
|
+
krons/session/session.py,sha256=bBK6rYPmYu5YcmU-oWoJL9pU8pdzr9Y4Z5wcIIiuirw,13221
|
|
90
|
+
krons/utils/__init__.py,sha256=V-jTKULdofjJXxcEHygefKV_v6XE4H3poCdxPLjvf_4,1718
|
|
91
|
+
krons/utils/_function_arg_parser.py,sha256=H5JVLBVY8W9ZNkZ4_YVtVVY1rFYvnIRhSrAhKEdj2Qc,3479
|
|
92
|
+
krons/utils/_hash.py,sha256=W2Ma9v8-INPaGkur7GTtbF8KwuXSJNSwk8DCNPRvx8Q,6859
|
|
93
|
+
krons/utils/_json_dump.py,sha256=rpBmr0NCmIKRdmpgn1nSWIHI3FTsGYsQjOa3YTxCi3M,12482
|
|
94
|
+
krons/utils/_lazy_init.py,sha256=bCx_W3dfzirB5KnAt6_jmbnwOk2xbU7-kgOhMQqzW70,1806
|
|
95
|
+
krons/utils/_pythonic_function_call.py,sha256=PAqnb-PNzVBvIrXh5-680mj7BlRiUziiHkjxELe0q78,8388
|
|
96
|
+
krons/utils/_to_list.py,sha256=RuiUWkoxHjD-2pqbbumar69AADCKYoGqSKL5FPu6LdM,6114
|
|
97
|
+
krons/utils/_to_num.py,sha256=NyyIL9Az1EaW6QFh9R7AeJdaUPoSRBNVBX9yj78wpok,3102
|
|
98
|
+
krons/utils/_utils.py,sha256=g1LAKX9-AwREb-XzXaAaHMCeSBlhtfWMu7GK1XDDAzg,11145
|
|
99
|
+
krons/utils/display.py,sha256=haAzWny-Ez1H6LphxNsEaYyFY3uctj2xbvgR8ZAUfJg,7312
|
|
100
|
+
krons/utils/concurrency/__init__.py,sha256=1HD-aY4Hevde0Hm0-VYa0eheT5OiwhlnDJtofIuV9wk,6754
|
|
101
|
+
krons/utils/concurrency/_async_call.py,sha256=cb7iXphip1zKPsim6whf-nCvdopq1spQNqx7sWxiejo,10233
|
|
102
|
+
krons/utils/concurrency/_cancel.py,sha256=b9f6yT8gObS6Y3EWKoGzNfYxqM1ZrN_8ctfyIjT1m1U,3326
|
|
103
|
+
krons/utils/concurrency/_errors.py,sha256=8bG72f71OxWYTdQ9AmUnI20UjEz0UYsWjQayter4CNI,2603
|
|
104
|
+
krons/utils/concurrency/_patterns.py,sha256=Xl31p63JkU370N9bA05uu60GDXrgwm1DHCjEq2U8-oo,11540
|
|
105
|
+
krons/utils/concurrency/_primitives.py,sha256=D1Rl1hujXXPdL4Mw6eW5EN8utM3bh8vmmFtXmuvsDw0,9024
|
|
106
|
+
krons/utils/concurrency/_priority_queue.py,sha256=wGi6ESS6AIZ0QNRBQR5UwcSQI5GhKjATBC_aEw6c0aQ,4342
|
|
107
|
+
krons/utils/concurrency/_resource_tracker.py,sha256=aBLTpSaUsUCtRLEHzIaBYu0NOuACFbIt3JGACo7K-0E,3179
|
|
108
|
+
krons/utils/concurrency/_run_async.py,sha256=A_vuPi9-wWRr3oXiAMnv3l7MV2B76jkBXoVztX_Vcgo,1940
|
|
109
|
+
krons/utils/concurrency/_task.py,sha256=4ivkiUUbutheoYZ-G8-mTfHX4YgWguGIy1v5hSU871w,2528
|
|
110
|
+
krons/utils/concurrency/_utils.py,sha256=CyH_z4prYFeCFgwk4Pc3q0m5NRzDB2TP-G2oxdM_-C0,2136
|
|
111
|
+
krons/utils/fuzzy/__init__.py,sha256=aztwfirLUDf8i-NukKhER1Pp0cZBcgtD92G1n_I4cq4,502
|
|
112
|
+
krons/utils/fuzzy/_extract_json.py,sha256=6Y-QEfXrTBdaNmlbMfVm6xJPBKI0RBbr_t0VYGE7nMo,2922
|
|
113
|
+
krons/utils/fuzzy/_fuzzy_json.py,sha256=hV6v9YkQpGxwOnhpLM6jkrG5fZKYluMTxgdqsk5sTew,9151
|
|
114
|
+
krons/utils/fuzzy/_fuzzy_match.py,sha256=6uDoKwqEnms_NMT2T4GB0LC9hhyeuEOOCAu39vO1COA,4953
|
|
115
|
+
krons/utils/fuzzy/_string_similarity.py,sha256=4G0lgBek8zgRcgKi6V0npwRKdkdmQ_wfayr3eCLZmEY,6155
|
|
116
|
+
krons/utils/fuzzy/_to_dict.py,sha256=cS-7NPKIePFlsGSRExCnBRPn7qHIHmcqR1tQBl5tRjE,12941
|
|
117
|
+
krons/utils/schemas/__init__.py,sha256=Si_UjyztaT0Shi85ISs6ESpTLohk9yLSYdy2x4-82Yo,701
|
|
118
|
+
krons/utils/schemas/_breakdown_pydantic_annotation.py,sha256=wfgrCnpPP74UpDyeOxox4uZgVEJZU7UBiBwZHL0ocT0,4075
|
|
119
|
+
krons/utils/schemas/_formatter.py,sha256=DSxYkJDNncno1T_FSEAa1B3BrONfR_swFbd1AOtrtcg,2682
|
|
120
|
+
krons/utils/schemas/_minimal_yaml.py,sha256=IhbPmInpLpuQpPcTtW1noLoVi4JLFBUL2aRaeLvoB2Q,4652
|
|
121
|
+
krons/utils/schemas/_typescript.py,sha256=XrbUQBbWxhzwuAXS6w54vwBno9Bg3dPpqZFRPPQIKBg,5240
|
|
122
|
+
krons/utils/sql/__init__.py,sha256=yNjm9Dr-ZjrZSD3Lext7fPR80qX5svGT2PnXqlb5qXs,264
|
|
123
|
+
krons/utils/sql/_sql_validation.py,sha256=smxNU3HjPhQuRK5ehG9Fl4DeljKK9tqUQIvRUopgvc8,4229
|
|
124
|
+
krons/utils/validators/__init__.py,sha256=qmCYoL6fQL1O6-GcfcUARii_fjXYNed6rKZWOp3skj8,87
|
|
125
|
+
krons/utils/validators/_validate_image_url.py,sha256=WAffNY3WpPFe_lqFLHumJS0_hm92NwIOmDOK1GR61ew,1858
|
|
126
|
+
krons/work/__init__.py,sha256=8C3ypK0FInl6YSos-F_MkuDhu_Vb_uN8HEegFq8pvwc,3541
|
|
127
|
+
krons/work/engine.py,sha256=ZHZzzRqedpLEkcX5eQ6zZQMXYfgmLMRN2JOwkLajND4,10924
|
|
128
|
+
krons/work/form.py,sha256=QwXYclRR-MxneNLF0CKbMvk_K-piZBmMXyCd_Y3XOeE,7264
|
|
129
|
+
krons/work/report.py,sha256=wxjMGnUc8b2Jn26l0t0k0cWetZFDyvyqBz0ldae4BD0,9027
|
|
130
|
+
krons/work/worker.py,sha256=hK7t5ztG_5wKPScwjtsctP4-ob6bHw9WKRJTw_gw_Fc,8494
|
|
131
|
+
krons/work/operations/__init__.py,sha256=vU-jy0Xy25W4vj98wV3sk3c8x6hKc5sf4nW3U_FQGdY,999
|
|
132
|
+
krons/work/operations/builder.py,sha256=_OGvooSl8s3Pmx8En15SX4XxQ12wF2ZszwVb5Hqzdpc,7779
|
|
133
|
+
krons/work/operations/context.py,sha256=rMcKR8kJkVk-7X1nW8LGoSjW4Eaj66LM46El8wwURmU,5323
|
|
134
|
+
krons/work/operations/flow.py,sha256=RL_GIIKlIURsbLp4-xRA7bJukeCVx0b_garodGd1NhI,14803
|
|
135
|
+
krons/work/operations/node.py,sha256=3NbM2o22oMpFXy6I7osGKIOIzJ69r5Bby99LHrNifr4,3374
|
|
136
|
+
krons/work/operations/registry.py,sha256=cVQA36_jgr9bxRiCsVM_plGPrTVr08vci1aio3olZyM,3483
|
|
137
|
+
krons/work/rules/__init__.py,sha256=oxBsYI3vxAp85G1pMIpQM_84HUYwHbB1lxa9t4uB6YY,1187
|
|
138
|
+
krons/work/rules/registry.py,sha256=JFdwcIVtysntj6wMY3bO7-hqwNU7QIoIbEQuhsy5O4U,4742
|
|
139
|
+
krons/work/rules/rule.py,sha256=uKjjiBwgzryiAOyTUI2YiqSyFg3QluvNRJ09EwtrbK8,9471
|
|
140
|
+
krons/work/rules/validator.py,sha256=CbbdueLI_6JvbbG0yvcljyhjO3HhpF4mlfBTzdhP4jA,7240
|
|
141
|
+
krons/work/rules/common/__init__.py,sha256=U0rEcHOxLftR4-xJNuuXMSDYFAvbs0KzwV3GhlZcUrY,1026
|
|
142
|
+
krons/work/rules/common/boolean.py,sha256=zX9i-oggejwFA0QYQSj1rDU1epqqpUe-ARFS4aol3qY,2644
|
|
143
|
+
krons/work/rules/common/choice.py,sha256=QT0qMDvoPHTGjYeybRkZX8oolIy8Y3iQIqehoV28cco,3264
|
|
144
|
+
krons/work/rules/common/mapping.py,sha256=Loq54MNEtwpnHN0aypTjFOqwoOKLEysddHh-JESedvs,3824
|
|
145
|
+
krons/work/rules/common/model.py,sha256=xmM6coEThf_fgIiqJiyDgvdfib_FpVeY6LgWPVcWSwU,3026
|
|
146
|
+
krons/work/rules/common/number.py,sha256=cCukgMSpQu5RdYK5rXAUyop9qXgDRfLCioMvE8kIzHg,3162
|
|
147
|
+
krons/work/rules/common/string.py,sha256=zHp_OLh0FL4PvmSlyDTEzb2I97-DBSEyI2zcMo10voA,5090
|
|
148
|
+
krons-0.2.1.dist-info/METADATA,sha256=O9pmDvpEfTq1HydsJRGUwTA6IPn_veB57Em2udfOO9g,2527
|
|
149
|
+
krons-0.2.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
150
|
+
krons-0.2.1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
151
|
+
krons-0.2.1.dist-info/RECORD,,
|