ouroboros-ai 0.1.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.
Potentially problematic release.
This version of ouroboros-ai might be problematic. Click here for more details.
- ouroboros/__init__.py +15 -0
- ouroboros/__main__.py +9 -0
- ouroboros/bigbang/__init__.py +39 -0
- ouroboros/bigbang/ambiguity.py +464 -0
- ouroboros/bigbang/interview.py +530 -0
- ouroboros/bigbang/seed_generator.py +610 -0
- ouroboros/cli/__init__.py +9 -0
- ouroboros/cli/commands/__init__.py +7 -0
- ouroboros/cli/commands/config.py +79 -0
- ouroboros/cli/commands/init.py +425 -0
- ouroboros/cli/commands/run.py +201 -0
- ouroboros/cli/commands/status.py +85 -0
- ouroboros/cli/formatters/__init__.py +31 -0
- ouroboros/cli/formatters/panels.py +157 -0
- ouroboros/cli/formatters/progress.py +112 -0
- ouroboros/cli/formatters/tables.py +166 -0
- ouroboros/cli/main.py +60 -0
- ouroboros/config/__init__.py +81 -0
- ouroboros/config/loader.py +292 -0
- ouroboros/config/models.py +332 -0
- ouroboros/core/__init__.py +62 -0
- ouroboros/core/ac_tree.py +401 -0
- ouroboros/core/context.py +472 -0
- ouroboros/core/errors.py +246 -0
- ouroboros/core/seed.py +212 -0
- ouroboros/core/types.py +205 -0
- ouroboros/evaluation/__init__.py +110 -0
- ouroboros/evaluation/consensus.py +350 -0
- ouroboros/evaluation/mechanical.py +351 -0
- ouroboros/evaluation/models.py +235 -0
- ouroboros/evaluation/pipeline.py +286 -0
- ouroboros/evaluation/semantic.py +302 -0
- ouroboros/evaluation/trigger.py +278 -0
- ouroboros/events/__init__.py +5 -0
- ouroboros/events/base.py +80 -0
- ouroboros/events/decomposition.py +153 -0
- ouroboros/events/evaluation.py +248 -0
- ouroboros/execution/__init__.py +44 -0
- ouroboros/execution/atomicity.py +451 -0
- ouroboros/execution/decomposition.py +481 -0
- ouroboros/execution/double_diamond.py +1386 -0
- ouroboros/execution/subagent.py +275 -0
- ouroboros/observability/__init__.py +63 -0
- ouroboros/observability/drift.py +383 -0
- ouroboros/observability/logging.py +504 -0
- ouroboros/observability/retrospective.py +338 -0
- ouroboros/orchestrator/__init__.py +78 -0
- ouroboros/orchestrator/adapter.py +391 -0
- ouroboros/orchestrator/events.py +278 -0
- ouroboros/orchestrator/runner.py +597 -0
- ouroboros/orchestrator/session.py +486 -0
- ouroboros/persistence/__init__.py +23 -0
- ouroboros/persistence/checkpoint.py +511 -0
- ouroboros/persistence/event_store.py +183 -0
- ouroboros/persistence/migrations/__init__.py +1 -0
- ouroboros/persistence/migrations/runner.py +100 -0
- ouroboros/persistence/migrations/scripts/001_initial.sql +20 -0
- ouroboros/persistence/schema.py +56 -0
- ouroboros/persistence/uow.py +230 -0
- ouroboros/providers/__init__.py +28 -0
- ouroboros/providers/base.py +133 -0
- ouroboros/providers/claude_code_adapter.py +212 -0
- ouroboros/providers/litellm_adapter.py +316 -0
- ouroboros/py.typed +0 -0
- ouroboros/resilience/__init__.py +67 -0
- ouroboros/resilience/lateral.py +595 -0
- ouroboros/resilience/stagnation.py +727 -0
- ouroboros/routing/__init__.py +60 -0
- ouroboros/routing/complexity.py +272 -0
- ouroboros/routing/downgrade.py +664 -0
- ouroboros/routing/escalation.py +340 -0
- ouroboros/routing/router.py +204 -0
- ouroboros/routing/tiers.py +247 -0
- ouroboros/secondary/__init__.py +40 -0
- ouroboros/secondary/scheduler.py +467 -0
- ouroboros/secondary/todo_registry.py +483 -0
- ouroboros_ai-0.1.0.dist-info/METADATA +607 -0
- ouroboros_ai-0.1.0.dist-info/RECORD +81 -0
- ouroboros_ai-0.1.0.dist-info/WHEEL +4 -0
- ouroboros_ai-0.1.0.dist-info/entry_points.txt +2 -0
- ouroboros_ai-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"""Three-tier model configuration for Ouroboros.
|
|
2
|
+
|
|
3
|
+
This module implements the three-tier Progressive Adaptive LLM (PAL) routing system:
|
|
4
|
+
- Frugal (1x cost): Fast, cheap models for routine tasks
|
|
5
|
+
- Standard (10x cost): Balanced models for most work
|
|
6
|
+
- Frontier (30x cost): Most capable models for complex tasks
|
|
7
|
+
|
|
8
|
+
The tier system enables cost optimization by routing tasks to the appropriate
|
|
9
|
+
model based on complexity and context.
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
from ouroboros.routing.tiers import Tier, get_model_for_tier, get_tier_config
|
|
13
|
+
|
|
14
|
+
# Get model for a tier
|
|
15
|
+
result = get_model_for_tier(Tier.FRUGAL, config)
|
|
16
|
+
if result.is_ok:
|
|
17
|
+
model = result.value
|
|
18
|
+
print(f"Using model: {model.provider}/{model.model}")
|
|
19
|
+
|
|
20
|
+
# Get tier configuration
|
|
21
|
+
result = get_tier_config(Tier.STANDARD, config)
|
|
22
|
+
if result.is_ok:
|
|
23
|
+
tier_config = result.value
|
|
24
|
+
print(f"Cost factor: {tier_config.cost_factor}x")
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from enum import Enum
|
|
28
|
+
import random
|
|
29
|
+
|
|
30
|
+
from ouroboros.config.models import ModelConfig, OuroborosConfig, TierConfig
|
|
31
|
+
from ouroboros.core.errors import ConfigError
|
|
32
|
+
from ouroboros.core.types import Result
|
|
33
|
+
from ouroboros.observability.logging import get_logger
|
|
34
|
+
|
|
35
|
+
log = get_logger(__name__)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class Tier(str, Enum):
|
|
39
|
+
"""Model tier enumeration.
|
|
40
|
+
|
|
41
|
+
Three tiers with different cost/capability tradeoffs:
|
|
42
|
+
- FRUGAL: 1x cost, fastest and cheapest
|
|
43
|
+
- STANDARD: 10x cost, balanced performance
|
|
44
|
+
- FRONTIER: 30x cost, highest capability
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
FRUGAL = "frugal"
|
|
48
|
+
STANDARD = "standard"
|
|
49
|
+
FRONTIER = "frontier"
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def cost_multiplier(self) -> int:
|
|
53
|
+
"""Get the cost multiplier for this tier.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
Cost multiplier (1, 10, or 30).
|
|
57
|
+
"""
|
|
58
|
+
multipliers = {
|
|
59
|
+
Tier.FRUGAL: 1,
|
|
60
|
+
Tier.STANDARD: 10,
|
|
61
|
+
Tier.FRONTIER: 30,
|
|
62
|
+
}
|
|
63
|
+
return multipliers[self]
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def get_tier_config(
|
|
67
|
+
tier: Tier,
|
|
68
|
+
config: OuroborosConfig,
|
|
69
|
+
) -> Result[TierConfig, ConfigError]:
|
|
70
|
+
"""Get configuration for a specific tier.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
tier: The tier to get configuration for.
|
|
74
|
+
config: The Ouroboros configuration.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
Result containing TierConfig on success or ConfigError on failure.
|
|
78
|
+
|
|
79
|
+
Example:
|
|
80
|
+
result = get_tier_config(Tier.FRUGAL, config)
|
|
81
|
+
if result.is_ok:
|
|
82
|
+
tier_config = result.value
|
|
83
|
+
print(f"Cost factor: {tier_config.cost_factor}x")
|
|
84
|
+
else:
|
|
85
|
+
print(f"Error: {result.error}")
|
|
86
|
+
"""
|
|
87
|
+
tier_name = tier.value
|
|
88
|
+
|
|
89
|
+
# Check if tier exists in configuration
|
|
90
|
+
if tier_name not in config.economics.tiers:
|
|
91
|
+
error = ConfigError(
|
|
92
|
+
f"Tier '{tier_name}' not found in configuration",
|
|
93
|
+
config_key=f"economics.tiers.{tier_name}",
|
|
94
|
+
details={
|
|
95
|
+
"available_tiers": list(config.economics.tiers.keys()),
|
|
96
|
+
"requested_tier": tier_name,
|
|
97
|
+
},
|
|
98
|
+
)
|
|
99
|
+
log.error(
|
|
100
|
+
"tier.config.missing",
|
|
101
|
+
tier=tier_name,
|
|
102
|
+
available_tiers=list(config.economics.tiers.keys()),
|
|
103
|
+
)
|
|
104
|
+
return Result.err(error)
|
|
105
|
+
|
|
106
|
+
tier_config = config.economics.tiers[tier_name]
|
|
107
|
+
|
|
108
|
+
# Validate tier has models configured
|
|
109
|
+
if not tier_config.models:
|
|
110
|
+
error = ConfigError(
|
|
111
|
+
f"Tier '{tier_name}' has no models configured",
|
|
112
|
+
config_key=f"economics.tiers.{tier_name}.models",
|
|
113
|
+
details={
|
|
114
|
+
"tier": tier_name,
|
|
115
|
+
"cost_factor": tier_config.cost_factor,
|
|
116
|
+
},
|
|
117
|
+
)
|
|
118
|
+
log.error(
|
|
119
|
+
"tier.config.no_models",
|
|
120
|
+
tier=tier_name,
|
|
121
|
+
cost_factor=tier_config.cost_factor,
|
|
122
|
+
)
|
|
123
|
+
return Result.err(error)
|
|
124
|
+
|
|
125
|
+
# Validate cost factor matches expected multiplier
|
|
126
|
+
expected_multiplier = tier.cost_multiplier
|
|
127
|
+
if tier_config.cost_factor != expected_multiplier:
|
|
128
|
+
error = ConfigError(
|
|
129
|
+
f"Tier '{tier_name}' has invalid cost factor: "
|
|
130
|
+
f"expected {expected_multiplier}, got {tier_config.cost_factor}",
|
|
131
|
+
config_key=f"economics.tiers.{tier_name}.cost_factor",
|
|
132
|
+
details={
|
|
133
|
+
"tier": tier_name,
|
|
134
|
+
"expected_cost_factor": expected_multiplier,
|
|
135
|
+
"actual_cost_factor": tier_config.cost_factor,
|
|
136
|
+
},
|
|
137
|
+
)
|
|
138
|
+
log.error(
|
|
139
|
+
"tier.config.invalid_cost_factor",
|
|
140
|
+
tier=tier_name,
|
|
141
|
+
expected=expected_multiplier,
|
|
142
|
+
actual=tier_config.cost_factor,
|
|
143
|
+
)
|
|
144
|
+
return Result.err(error)
|
|
145
|
+
|
|
146
|
+
log.debug(
|
|
147
|
+
"tier.config.retrieved",
|
|
148
|
+
tier=tier_name,
|
|
149
|
+
cost_factor=tier_config.cost_factor,
|
|
150
|
+
model_count=len(tier_config.models),
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
return Result.ok(tier_config)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def get_model_for_tier(
|
|
157
|
+
tier: Tier,
|
|
158
|
+
config: OuroborosConfig,
|
|
159
|
+
) -> Result[ModelConfig, ConfigError]:
|
|
160
|
+
"""Get a model for the specified tier.
|
|
161
|
+
|
|
162
|
+
Selects a random model from the tier's configured models to enable
|
|
163
|
+
load balancing and provider diversity.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
tier: The tier to get a model for.
|
|
167
|
+
config: The Ouroboros configuration.
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
Result containing ModelConfig on success or ConfigError on failure.
|
|
171
|
+
|
|
172
|
+
Example:
|
|
173
|
+
result = get_model_for_tier(Tier.STANDARD, config)
|
|
174
|
+
if result.is_ok:
|
|
175
|
+
model = result.value
|
|
176
|
+
print(f"Selected: {model.provider}/{model.model}")
|
|
177
|
+
else:
|
|
178
|
+
print(f"Error: {result.error}")
|
|
179
|
+
"""
|
|
180
|
+
# Get tier configuration
|
|
181
|
+
tier_result = get_tier_config(tier, config)
|
|
182
|
+
if tier_result.is_err:
|
|
183
|
+
return Result.err(tier_result.error)
|
|
184
|
+
|
|
185
|
+
tier_config = tier_result.value
|
|
186
|
+
|
|
187
|
+
# Select random model from tier (for load balancing)
|
|
188
|
+
model = random.choice(tier_config.models)
|
|
189
|
+
|
|
190
|
+
log.info(
|
|
191
|
+
"tier.model.selected",
|
|
192
|
+
tier=tier.value,
|
|
193
|
+
provider=model.provider,
|
|
194
|
+
model=model.model,
|
|
195
|
+
cost_factor=tier_config.cost_factor,
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
return Result.ok(model)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def validate_tier_configuration(
|
|
202
|
+
config: OuroborosConfig,
|
|
203
|
+
) -> Result[None, ConfigError]:
|
|
204
|
+
"""Validate that all three tiers are properly configured.
|
|
205
|
+
|
|
206
|
+
Checks:
|
|
207
|
+
- All three tiers (frugal, standard, frontier) exist
|
|
208
|
+
- Each tier has at least one model
|
|
209
|
+
- Cost factors match expected values (1x, 10x, 30x)
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
config: The Ouroboros configuration to validate.
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
Result containing None on success or ConfigError on failure.
|
|
216
|
+
|
|
217
|
+
Example:
|
|
218
|
+
result = validate_tier_configuration(config)
|
|
219
|
+
if result.is_err:
|
|
220
|
+
print(f"Configuration error: {result.error}")
|
|
221
|
+
"""
|
|
222
|
+
errors = []
|
|
223
|
+
|
|
224
|
+
# Validate all three tiers exist and are properly configured
|
|
225
|
+
for tier in Tier:
|
|
226
|
+
result = get_tier_config(tier, config)
|
|
227
|
+
if result.is_err:
|
|
228
|
+
errors.append(str(result.error))
|
|
229
|
+
|
|
230
|
+
if errors:
|
|
231
|
+
error = ConfigError(
|
|
232
|
+
"Tier configuration validation failed",
|
|
233
|
+
config_key="economics.tiers",
|
|
234
|
+
details={
|
|
235
|
+
"errors": errors,
|
|
236
|
+
"required_tiers": [t.value for t in Tier],
|
|
237
|
+
},
|
|
238
|
+
)
|
|
239
|
+
log.error(
|
|
240
|
+
"tier.validation.failed",
|
|
241
|
+
error_count=len(errors),
|
|
242
|
+
errors=errors,
|
|
243
|
+
)
|
|
244
|
+
return Result.err(error)
|
|
245
|
+
|
|
246
|
+
log.info("tier.validation.passed", tier_count=len(Tier))
|
|
247
|
+
return Result.ok(None)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""Secondary Loop module for TODO management and batch processing.
|
|
2
|
+
|
|
3
|
+
This module implements Phase 6 of the Ouroboros execution model:
|
|
4
|
+
- TODO Registry: Captures improvements discovered during execution
|
|
5
|
+
- Secondary Loop Scheduler: Processes TODOs after primary goal achievement
|
|
6
|
+
|
|
7
|
+
Components:
|
|
8
|
+
Todo: Immutable TODO item model
|
|
9
|
+
Priority: TODO priority enum (HIGH, MEDIUM, LOW)
|
|
10
|
+
TodoStatus: TODO lifecycle status enum
|
|
11
|
+
TodoRegistry: Non-blocking TODO registration and persistence
|
|
12
|
+
SecondaryLoopScheduler: Batch processing of TODOs after primary completion
|
|
13
|
+
BatchStatus: Status of batch processing run
|
|
14
|
+
BatchSummary: Summary of batch processing results
|
|
15
|
+
TodoResult: Result of processing a single TODO
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from ouroboros.secondary.scheduler import (
|
|
19
|
+
BatchStatus,
|
|
20
|
+
BatchSummary,
|
|
21
|
+
SecondaryLoopScheduler,
|
|
22
|
+
TodoResult,
|
|
23
|
+
)
|
|
24
|
+
from ouroboros.secondary.todo_registry import (
|
|
25
|
+
Priority,
|
|
26
|
+
Todo,
|
|
27
|
+
TodoRegistry,
|
|
28
|
+
TodoStatus,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
__all__ = [
|
|
32
|
+
"BatchStatus",
|
|
33
|
+
"BatchSummary",
|
|
34
|
+
"Priority",
|
|
35
|
+
"SecondaryLoopScheduler",
|
|
36
|
+
"Todo",
|
|
37
|
+
"TodoRegistry",
|
|
38
|
+
"TodoResult",
|
|
39
|
+
"TodoStatus",
|
|
40
|
+
]
|