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,31 @@
1
+ """Rich formatters for CLI output.
2
+
3
+ This module provides a shared Console instance and exports all formatters
4
+ for consistent terminal output across the Ouroboros CLI.
5
+
6
+ Semantic Colors:
7
+ - green: success
8
+ - yellow: warning
9
+ - red: error
10
+ - blue: info
11
+ """
12
+
13
+ from rich.console import Console
14
+ from rich.theme import Theme
15
+
16
+ # Semantic color theme for consistent output
17
+ OUROBOROS_THEME = Theme(
18
+ {
19
+ "success": "green",
20
+ "warning": "yellow",
21
+ "error": "red",
22
+ "info": "blue",
23
+ "muted": "dim",
24
+ "highlight": "bold cyan",
25
+ }
26
+ )
27
+
28
+ # Shared Console instance for all CLI modules
29
+ console = Console(theme=OUROBOROS_THEME)
30
+
31
+ __all__ = ["console", "OUROBOROS_THEME"]
@@ -0,0 +1,157 @@
1
+ """Rich panels for important messages.
2
+
3
+ Provides panel templates for displaying info, warning, error,
4
+ and success messages with consistent styling.
5
+ """
6
+
7
+ from rich.panel import Panel
8
+
9
+ from ouroboros.cli.formatters import console
10
+
11
+
12
+ def info_panel(
13
+ message: str,
14
+ title: str = "Info",
15
+ *,
16
+ expand: bool = False,
17
+ ) -> Panel:
18
+ """Create an info panel with blue styling.
19
+
20
+ Args:
21
+ message: Message content to display.
22
+ title: Panel title.
23
+ expand: Whether to expand panel to full width.
24
+
25
+ Returns:
26
+ Configured Rich Panel.
27
+ """
28
+ return Panel(
29
+ f"[info]{message}[/]",
30
+ title=f"[bold blue]{title}[/]",
31
+ border_style="blue",
32
+ expand=expand,
33
+ )
34
+
35
+
36
+ def warning_panel(
37
+ message: str,
38
+ title: str = "Warning",
39
+ *,
40
+ expand: bool = False,
41
+ ) -> Panel:
42
+ """Create a warning panel with yellow styling.
43
+
44
+ Args:
45
+ message: Message content to display.
46
+ title: Panel title.
47
+ expand: Whether to expand panel to full width.
48
+
49
+ Returns:
50
+ Configured Rich Panel.
51
+ """
52
+ return Panel(
53
+ f"[warning]{message}[/]",
54
+ title=f"[bold yellow]{title}[/]",
55
+ border_style="yellow",
56
+ expand=expand,
57
+ )
58
+
59
+
60
+ def error_panel(
61
+ message: str,
62
+ title: str = "Error",
63
+ *,
64
+ expand: bool = False,
65
+ ) -> Panel:
66
+ """Create an error panel with red styling.
67
+
68
+ Args:
69
+ message: Message content to display.
70
+ title: Panel title.
71
+ expand: Whether to expand panel to full width.
72
+
73
+ Returns:
74
+ Configured Rich Panel.
75
+ """
76
+ return Panel(
77
+ f"[error]{message}[/]",
78
+ title=f"[bold red]{title}[/]",
79
+ border_style="red",
80
+ expand=expand,
81
+ )
82
+
83
+
84
+ def success_panel(
85
+ message: str,
86
+ title: str = "Success",
87
+ *,
88
+ expand: bool = False,
89
+ ) -> Panel:
90
+ """Create a success panel with green styling.
91
+
92
+ Args:
93
+ message: Message content to display.
94
+ title: Panel title.
95
+ expand: Whether to expand panel to full width.
96
+
97
+ Returns:
98
+ Configured Rich Panel.
99
+ """
100
+ return Panel(
101
+ f"[success]{message}[/]",
102
+ title=f"[bold green]{title}[/]",
103
+ border_style="green",
104
+ expand=expand,
105
+ )
106
+
107
+
108
+ def print_info(message: str, title: str = "Info") -> None:
109
+ """Print an info message in a panel.
110
+
111
+ Args:
112
+ message: Message content to display.
113
+ title: Panel title.
114
+ """
115
+ console.print(info_panel(message, title))
116
+
117
+
118
+ def print_warning(message: str, title: str = "Warning") -> None:
119
+ """Print a warning message in a panel.
120
+
121
+ Args:
122
+ message: Message content to display.
123
+ title: Panel title.
124
+ """
125
+ console.print(warning_panel(message, title))
126
+
127
+
128
+ def print_error(message: str, title: str = "Error") -> None:
129
+ """Print an error message in a panel.
130
+
131
+ Args:
132
+ message: Message content to display.
133
+ title: Panel title.
134
+ """
135
+ console.print(error_panel(message, title))
136
+
137
+
138
+ def print_success(message: str, title: str = "Success") -> None:
139
+ """Print a success message in a panel.
140
+
141
+ Args:
142
+ message: Message content to display.
143
+ title: Panel title.
144
+ """
145
+ console.print(success_panel(message, title))
146
+
147
+
148
+ __all__ = [
149
+ "info_panel",
150
+ "warning_panel",
151
+ "error_panel",
152
+ "success_panel",
153
+ "print_info",
154
+ "print_warning",
155
+ "print_error",
156
+ "print_success",
157
+ ]
@@ -0,0 +1,112 @@
1
+ """Rich progress bars for async operations.
2
+
3
+ Provides spinner-based progress indication for long-running operations,
4
+ with async-aware context managers for clean progress display.
5
+ """
6
+
7
+ from collections.abc import AsyncIterator, Iterator
8
+ from contextlib import asynccontextmanager, contextmanager
9
+
10
+ from rich.progress import Progress, SpinnerColumn, TaskID, TextColumn, TimeElapsedColumn
11
+
12
+ from ouroboros.cli.formatters import console
13
+
14
+
15
+ def create_progress() -> Progress:
16
+ """Create a Progress instance with spinner for async operations.
17
+
18
+ Returns:
19
+ Progress instance configured with spinner, text, and elapsed time columns.
20
+ """
21
+ return Progress(
22
+ SpinnerColumn(),
23
+ TextColumn("[progress.description]{task.description}"),
24
+ TimeElapsedColumn(),
25
+ console=console,
26
+ transient=True,
27
+ )
28
+
29
+
30
+ @contextmanager
31
+ def progress_spinner(description: str = "Processing...") -> Iterator[tuple[Progress, TaskID]]:
32
+ """Context manager for displaying a progress spinner.
33
+
34
+ Args:
35
+ description: Text description to display alongside the spinner.
36
+
37
+ Yields:
38
+ Tuple of (Progress instance, TaskID) for the running task.
39
+
40
+ Example:
41
+ with progress_spinner("Loading configuration...") as (progress, task):
42
+ # Do work here
43
+ pass
44
+ """
45
+ progress = create_progress()
46
+ with progress:
47
+ task_id = progress.add_task(description, total=None)
48
+ yield progress, task_id
49
+
50
+
51
+ @asynccontextmanager
52
+ async def async_progress_spinner(
53
+ description: str = "Processing...",
54
+ ) -> AsyncIterator[tuple[Progress, TaskID]]:
55
+ """Async context manager for displaying a progress spinner.
56
+
57
+ Use this for async operations that need visual progress indication.
58
+
59
+ Args:
60
+ description: Text description to display alongside the spinner.
61
+
62
+ Yields:
63
+ Tuple of (Progress instance, TaskID) for the running task.
64
+
65
+ Example:
66
+ async with async_progress_spinner("Fetching data...") as (progress, task):
67
+ await fetch_data()
68
+ """
69
+ progress = create_progress()
70
+ with progress:
71
+ task_id = progress.add_task(description, total=None)
72
+ yield progress, task_id
73
+
74
+
75
+ def create_determinate_progress(
76
+ total: float,
77
+ description: str = "Processing...",
78
+ ) -> tuple[Progress, TaskID]:
79
+ """Create a determinate progress bar for operations with known total.
80
+
81
+ Args:
82
+ total: Total number of steps/items.
83
+ description: Text description to display.
84
+
85
+ Returns:
86
+ Tuple of (Progress instance, TaskID). Caller must manage Progress lifecycle.
87
+
88
+ Example:
89
+ progress, task = create_determinate_progress(100, "Processing files...")
90
+ with progress:
91
+ for i in range(100):
92
+ do_work()
93
+ progress.update(task, advance=1)
94
+ """
95
+ progress = Progress(
96
+ SpinnerColumn(),
97
+ TextColumn("[progress.description]{task.description}"),
98
+ "[progress.percentage]{task.percentage:>3.0f}%",
99
+ TimeElapsedColumn(),
100
+ console=console,
101
+ transient=True,
102
+ )
103
+ task_id = progress.add_task(description, total=total)
104
+ return progress, task_id
105
+
106
+
107
+ __all__ = [
108
+ "create_progress",
109
+ "progress_spinner",
110
+ "async_progress_spinner",
111
+ "create_determinate_progress",
112
+ ]
@@ -0,0 +1,166 @@
1
+ """Rich tables for structured data display.
2
+
3
+ Provides table formatting utilities with consistent styling
4
+ for displaying structured data in the Ouroboros CLI.
5
+ """
6
+
7
+ from typing import Any
8
+
9
+ from rich.table import Table
10
+
11
+ from ouroboros.cli.formatters import console
12
+
13
+
14
+ def create_table(
15
+ title: str | None = None,
16
+ *,
17
+ show_header: bool = True,
18
+ show_lines: bool = False,
19
+ border_style: str = "blue",
20
+ header_style: str = "bold cyan",
21
+ row_styles: list[str] | None = None,
22
+ ) -> Table:
23
+ """Create a Rich Table with consistent Ouroboros styling.
24
+
25
+ Args:
26
+ title: Optional table title.
27
+ show_header: Whether to show the header row.
28
+ show_lines: Whether to show lines between rows.
29
+ border_style: Style for table borders.
30
+ header_style: Style for header row.
31
+ row_styles: Alternating row styles (default: subtle alternation).
32
+
33
+ Returns:
34
+ Configured Rich Table instance.
35
+
36
+ Example:
37
+ table = create_table("Results")
38
+ table.add_column("Name", style="cyan")
39
+ table.add_column("Status", style="green")
40
+ table.add_row("Task 1", "Complete")
41
+ print_table(table)
42
+ """
43
+ if row_styles is None:
44
+ row_styles = ["", "dim"]
45
+
46
+ return Table(
47
+ title=title,
48
+ show_header=show_header,
49
+ show_lines=show_lines,
50
+ border_style=border_style,
51
+ header_style=header_style,
52
+ row_styles=row_styles,
53
+ )
54
+
55
+
56
+ def create_key_value_table(
57
+ data: dict[str, Any],
58
+ title: str | None = None,
59
+ *,
60
+ key_style: str = "cyan",
61
+ value_style: str = "",
62
+ ) -> Table:
63
+ """Create a two-column table for key-value data.
64
+
65
+ Args:
66
+ data: Dictionary of key-value pairs to display.
67
+ title: Optional table title.
68
+ key_style: Style for the key column.
69
+ value_style: Style for the value column.
70
+
71
+ Returns:
72
+ Rich Table populated with the key-value data.
73
+
74
+ Example:
75
+ info = {"Version": "1.0.0", "Status": "Running"}
76
+ table = create_key_value_table(info, "System Info")
77
+ print_table(table)
78
+ """
79
+ table = create_table(title, show_header=False)
80
+ table.add_column("Key", style=key_style, no_wrap=True)
81
+ table.add_column("Value", style=value_style)
82
+
83
+ for key, value in data.items():
84
+ table.add_row(str(key), str(value))
85
+
86
+ return table
87
+
88
+
89
+ def create_status_table(
90
+ items: list[dict[str, Any]],
91
+ title: str | None = None,
92
+ *,
93
+ name_key: str = "name",
94
+ status_key: str = "status",
95
+ ) -> Table:
96
+ """Create a table for displaying status information.
97
+
98
+ Automatically applies semantic colors based on status values:
99
+ - "success", "complete", "running": green
100
+ - "warning", "pending": yellow
101
+ - "error", "failed": red
102
+
103
+ Args:
104
+ items: List of dictionaries containing at least name and status.
105
+ title: Optional table title.
106
+ name_key: Key for the name/identifier field.
107
+ status_key: Key for the status field.
108
+
109
+ Returns:
110
+ Rich Table populated with status information.
111
+
112
+ Example:
113
+ items = [
114
+ {"name": "Task 1", "status": "complete"},
115
+ {"name": "Task 2", "status": "running"},
116
+ ]
117
+ table = create_status_table(items, "Task Status")
118
+ print_table(table)
119
+ """
120
+ table = create_table(title)
121
+ table.add_column("Name", style="cyan", no_wrap=True)
122
+ table.add_column("Status", justify="center")
123
+
124
+ for item in items:
125
+ name = str(item.get(name_key, ""))
126
+ status = str(item.get(status_key, ""))
127
+ status_style = _get_status_style(status)
128
+ table.add_row(name, f"[{status_style}]{status}[/]")
129
+
130
+ return table
131
+
132
+
133
+ def _get_status_style(status: str) -> str:
134
+ """Get semantic style for a status value.
135
+
136
+ Args:
137
+ status: Status string to style.
138
+
139
+ Returns:
140
+ Style string for Rich formatting.
141
+ """
142
+ status_lower = status.lower()
143
+ if status_lower in ("success", "complete", "completed", "running", "active", "ok"):
144
+ return "success"
145
+ elif status_lower in ("warning", "pending", "waiting", "paused"):
146
+ return "warning"
147
+ elif status_lower in ("error", "failed", "failure", "critical"):
148
+ return "error"
149
+ return ""
150
+
151
+
152
+ def print_table(table: Table) -> None:
153
+ """Print a Rich Table to the shared console.
154
+
155
+ Args:
156
+ table: Table to print.
157
+ """
158
+ console.print(table)
159
+
160
+
161
+ __all__ = [
162
+ "create_table",
163
+ "create_key_value_table",
164
+ "create_status_table",
165
+ "print_table",
166
+ ]
ouroboros/cli/main.py ADDED
@@ -0,0 +1,60 @@
1
+ """Ouroboros CLI main entry point.
2
+
3
+ This module defines the main Typer application and registers
4
+ all command groups for the Ouroboros CLI.
5
+ """
6
+
7
+ from typing import Annotated
8
+
9
+ import typer
10
+
11
+ from ouroboros import __version__
12
+ from ouroboros.cli.commands import config, init, run, status
13
+ from ouroboros.cli.formatters import console
14
+
15
+ # Create the main Typer app
16
+ app = typer.Typer(
17
+ name="ouroboros",
18
+ help="Ouroboros - Self-Improving AI Workflow System",
19
+ no_args_is_help=True,
20
+ rich_markup_mode="rich",
21
+ )
22
+
23
+ # Register command groups
24
+ app.add_typer(init.app, name="init")
25
+ app.add_typer(run.app, name="run")
26
+ app.add_typer(config.app, name="config")
27
+ app.add_typer(status.app, name="status")
28
+
29
+
30
+ def version_callback(value: bool) -> None:
31
+ """Print version and exit."""
32
+ if value:
33
+ console.print(f"[bold cyan]Ouroboros[/] version [green]{__version__}[/]")
34
+ raise typer.Exit()
35
+
36
+
37
+ @app.callback()
38
+ def main(
39
+ version: Annotated[
40
+ bool | None,
41
+ typer.Option(
42
+ "--version",
43
+ "-V",
44
+ callback=version_callback,
45
+ is_eager=True,
46
+ help="Show version and exit.",
47
+ ),
48
+ ] = None,
49
+ ) -> None:
50
+ """Ouroboros - Self-Improving AI Workflow System.
51
+
52
+ A self-improving AI workflow system with 6 phases:
53
+ Big Bang, PAL Router, Execution, Resilience, Evaluation, and Consensus.
54
+
55
+ Use [bold cyan]ouroboros COMMAND --help[/] for command-specific help.
56
+ """
57
+ pass
58
+
59
+
60
+ __all__ = ["app", "main"]
@@ -0,0 +1,81 @@
1
+ """Configuration module for Ouroboros.
2
+
3
+ This module provides configuration loading, validation, and management
4
+ for the Ouroboros system. Configuration is stored in ~/.ouroboros/.
5
+
6
+ Main exports:
7
+ OuroborosConfig: Main configuration model
8
+ CredentialsConfig: Provider credentials model
9
+ TierConfig: Tier configuration model
10
+ load_config: Load config from YAML file
11
+ load_credentials: Load credentials from YAML file
12
+ create_default_config: Create default config files
13
+ config_exists: Check if config files exist
14
+
15
+ Usage:
16
+ from ouroboros.config import load_config, load_credentials
17
+
18
+ config = load_config()
19
+ credentials = load_credentials()
20
+
21
+ # Access configuration
22
+ default_tier = config.economics.default_tier
23
+ api_key = credentials.providers["openai"].api_key
24
+ """
25
+
26
+ from ouroboros.config.loader import (
27
+ config_exists,
28
+ create_default_config,
29
+ credentials_file_secure,
30
+ ensure_config_dir,
31
+ load_config,
32
+ load_credentials,
33
+ )
34
+ from ouroboros.config.models import (
35
+ ClarificationConfig,
36
+ ConsensusConfig,
37
+ CredentialsConfig,
38
+ DriftConfig,
39
+ EconomicsConfig,
40
+ EvaluationConfig,
41
+ ExecutionConfig,
42
+ LoggingConfig,
43
+ ModelConfig,
44
+ OuroborosConfig,
45
+ PersistenceConfig,
46
+ ProviderCredentials,
47
+ ResilienceConfig,
48
+ TierConfig,
49
+ get_config_dir,
50
+ get_default_config,
51
+ get_default_credentials,
52
+ )
53
+
54
+ __all__ = [
55
+ # Models
56
+ "OuroborosConfig",
57
+ "CredentialsConfig",
58
+ "TierConfig",
59
+ "ModelConfig",
60
+ "ProviderCredentials",
61
+ "EconomicsConfig",
62
+ "ClarificationConfig",
63
+ "ExecutionConfig",
64
+ "ResilienceConfig",
65
+ "EvaluationConfig",
66
+ "ConsensusConfig",
67
+ "PersistenceConfig",
68
+ "DriftConfig",
69
+ "LoggingConfig",
70
+ # Loader functions
71
+ "load_config",
72
+ "load_credentials",
73
+ "create_default_config",
74
+ "ensure_config_dir",
75
+ "config_exists",
76
+ "credentials_file_secure",
77
+ # Model helpers
78
+ "get_config_dir",
79
+ "get_default_config",
80
+ "get_default_credentials",
81
+ ]