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.

Files changed (81) hide show
  1. ouroboros/__init__.py +15 -0
  2. ouroboros/__main__.py +9 -0
  3. ouroboros/bigbang/__init__.py +39 -0
  4. ouroboros/bigbang/ambiguity.py +464 -0
  5. ouroboros/bigbang/interview.py +530 -0
  6. ouroboros/bigbang/seed_generator.py +610 -0
  7. ouroboros/cli/__init__.py +9 -0
  8. ouroboros/cli/commands/__init__.py +7 -0
  9. ouroboros/cli/commands/config.py +79 -0
  10. ouroboros/cli/commands/init.py +425 -0
  11. ouroboros/cli/commands/run.py +201 -0
  12. ouroboros/cli/commands/status.py +85 -0
  13. ouroboros/cli/formatters/__init__.py +31 -0
  14. ouroboros/cli/formatters/panels.py +157 -0
  15. ouroboros/cli/formatters/progress.py +112 -0
  16. ouroboros/cli/formatters/tables.py +166 -0
  17. ouroboros/cli/main.py +60 -0
  18. ouroboros/config/__init__.py +81 -0
  19. ouroboros/config/loader.py +292 -0
  20. ouroboros/config/models.py +332 -0
  21. ouroboros/core/__init__.py +62 -0
  22. ouroboros/core/ac_tree.py +401 -0
  23. ouroboros/core/context.py +472 -0
  24. ouroboros/core/errors.py +246 -0
  25. ouroboros/core/seed.py +212 -0
  26. ouroboros/core/types.py +205 -0
  27. ouroboros/evaluation/__init__.py +110 -0
  28. ouroboros/evaluation/consensus.py +350 -0
  29. ouroboros/evaluation/mechanical.py +351 -0
  30. ouroboros/evaluation/models.py +235 -0
  31. ouroboros/evaluation/pipeline.py +286 -0
  32. ouroboros/evaluation/semantic.py +302 -0
  33. ouroboros/evaluation/trigger.py +278 -0
  34. ouroboros/events/__init__.py +5 -0
  35. ouroboros/events/base.py +80 -0
  36. ouroboros/events/decomposition.py +153 -0
  37. ouroboros/events/evaluation.py +248 -0
  38. ouroboros/execution/__init__.py +44 -0
  39. ouroboros/execution/atomicity.py +451 -0
  40. ouroboros/execution/decomposition.py +481 -0
  41. ouroboros/execution/double_diamond.py +1386 -0
  42. ouroboros/execution/subagent.py +275 -0
  43. ouroboros/observability/__init__.py +63 -0
  44. ouroboros/observability/drift.py +383 -0
  45. ouroboros/observability/logging.py +504 -0
  46. ouroboros/observability/retrospective.py +338 -0
  47. ouroboros/orchestrator/__init__.py +78 -0
  48. ouroboros/orchestrator/adapter.py +391 -0
  49. ouroboros/orchestrator/events.py +278 -0
  50. ouroboros/orchestrator/runner.py +597 -0
  51. ouroboros/orchestrator/session.py +486 -0
  52. ouroboros/persistence/__init__.py +23 -0
  53. ouroboros/persistence/checkpoint.py +511 -0
  54. ouroboros/persistence/event_store.py +183 -0
  55. ouroboros/persistence/migrations/__init__.py +1 -0
  56. ouroboros/persistence/migrations/runner.py +100 -0
  57. ouroboros/persistence/migrations/scripts/001_initial.sql +20 -0
  58. ouroboros/persistence/schema.py +56 -0
  59. ouroboros/persistence/uow.py +230 -0
  60. ouroboros/providers/__init__.py +28 -0
  61. ouroboros/providers/base.py +133 -0
  62. ouroboros/providers/claude_code_adapter.py +212 -0
  63. ouroboros/providers/litellm_adapter.py +316 -0
  64. ouroboros/py.typed +0 -0
  65. ouroboros/resilience/__init__.py +67 -0
  66. ouroboros/resilience/lateral.py +595 -0
  67. ouroboros/resilience/stagnation.py +727 -0
  68. ouroboros/routing/__init__.py +60 -0
  69. ouroboros/routing/complexity.py +272 -0
  70. ouroboros/routing/downgrade.py +664 -0
  71. ouroboros/routing/escalation.py +340 -0
  72. ouroboros/routing/router.py +204 -0
  73. ouroboros/routing/tiers.py +247 -0
  74. ouroboros/secondary/__init__.py +40 -0
  75. ouroboros/secondary/scheduler.py +467 -0
  76. ouroboros/secondary/todo_registry.py +483 -0
  77. ouroboros_ai-0.1.0.dist-info/METADATA +607 -0
  78. ouroboros_ai-0.1.0.dist-info/RECORD +81 -0
  79. ouroboros_ai-0.1.0.dist-info/WHEEL +4 -0
  80. ouroboros_ai-0.1.0.dist-info/entry_points.txt +2 -0
  81. 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
+ ]