ctrlcode 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.
Files changed (75) hide show
  1. ctrlcode/__init__.py +8 -0
  2. ctrlcode/agents/__init__.py +29 -0
  3. ctrlcode/agents/cleanup.py +388 -0
  4. ctrlcode/agents/communication.py +439 -0
  5. ctrlcode/agents/observability.py +421 -0
  6. ctrlcode/agents/react_loop.py +297 -0
  7. ctrlcode/agents/registry.py +211 -0
  8. ctrlcode/agents/result_parser.py +242 -0
  9. ctrlcode/agents/workflow.py +723 -0
  10. ctrlcode/analysis/__init__.py +28 -0
  11. ctrlcode/analysis/ast_diff.py +163 -0
  12. ctrlcode/analysis/bug_detector.py +149 -0
  13. ctrlcode/analysis/code_graphs.py +329 -0
  14. ctrlcode/analysis/semantic.py +205 -0
  15. ctrlcode/analysis/static.py +183 -0
  16. ctrlcode/analysis/synthesizer.py +281 -0
  17. ctrlcode/analysis/tests.py +189 -0
  18. ctrlcode/cleanup/__init__.py +16 -0
  19. ctrlcode/cleanup/auto_merge.py +350 -0
  20. ctrlcode/cleanup/doc_gardening.py +388 -0
  21. ctrlcode/cleanup/pr_automation.py +330 -0
  22. ctrlcode/cleanup/scheduler.py +356 -0
  23. ctrlcode/config.py +380 -0
  24. ctrlcode/embeddings/__init__.py +6 -0
  25. ctrlcode/embeddings/embedder.py +192 -0
  26. ctrlcode/embeddings/vector_store.py +213 -0
  27. ctrlcode/fuzzing/__init__.py +24 -0
  28. ctrlcode/fuzzing/analyzer.py +280 -0
  29. ctrlcode/fuzzing/budget.py +112 -0
  30. ctrlcode/fuzzing/context.py +665 -0
  31. ctrlcode/fuzzing/context_fuzzer.py +506 -0
  32. ctrlcode/fuzzing/derived_orchestrator.py +732 -0
  33. ctrlcode/fuzzing/oracle_adapter.py +135 -0
  34. ctrlcode/linters/__init__.py +11 -0
  35. ctrlcode/linters/hand_rolled_utils.py +221 -0
  36. ctrlcode/linters/yolo_parsing.py +217 -0
  37. ctrlcode/metrics/__init__.py +6 -0
  38. ctrlcode/metrics/dashboard.py +283 -0
  39. ctrlcode/metrics/tech_debt.py +663 -0
  40. ctrlcode/paths.py +68 -0
  41. ctrlcode/permissions.py +179 -0
  42. ctrlcode/providers/__init__.py +15 -0
  43. ctrlcode/providers/anthropic.py +138 -0
  44. ctrlcode/providers/base.py +77 -0
  45. ctrlcode/providers/openai.py +197 -0
  46. ctrlcode/providers/parallel.py +104 -0
  47. ctrlcode/server.py +871 -0
  48. ctrlcode/session/__init__.py +6 -0
  49. ctrlcode/session/baseline.py +57 -0
  50. ctrlcode/session/manager.py +967 -0
  51. ctrlcode/skills/__init__.py +10 -0
  52. ctrlcode/skills/builtin/commit.toml +29 -0
  53. ctrlcode/skills/builtin/docs.toml +25 -0
  54. ctrlcode/skills/builtin/refactor.toml +33 -0
  55. ctrlcode/skills/builtin/review.toml +28 -0
  56. ctrlcode/skills/builtin/test.toml +28 -0
  57. ctrlcode/skills/loader.py +111 -0
  58. ctrlcode/skills/registry.py +139 -0
  59. ctrlcode/storage/__init__.py +19 -0
  60. ctrlcode/storage/history_db.py +708 -0
  61. ctrlcode/tools/__init__.py +220 -0
  62. ctrlcode/tools/bash.py +112 -0
  63. ctrlcode/tools/browser.py +352 -0
  64. ctrlcode/tools/executor.py +153 -0
  65. ctrlcode/tools/explore.py +486 -0
  66. ctrlcode/tools/mcp.py +108 -0
  67. ctrlcode/tools/observability.py +561 -0
  68. ctrlcode/tools/registry.py +193 -0
  69. ctrlcode/tools/todo.py +291 -0
  70. ctrlcode/tools/update.py +266 -0
  71. ctrlcode/tools/webfetch.py +147 -0
  72. ctrlcode-0.1.0.dist-info/METADATA +93 -0
  73. ctrlcode-0.1.0.dist-info/RECORD +75 -0
  74. ctrlcode-0.1.0.dist-info/WHEEL +4 -0
  75. ctrlcode-0.1.0.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,104 @@
1
+ """Parallel execution of provider calls for fuzzing."""
2
+
3
+ import asyncio
4
+ from typing import Any
5
+ from dataclasses import dataclass
6
+
7
+ from .base import Provider
8
+
9
+
10
+ @dataclass
11
+ class ProviderOutput:
12
+ """Result from a provider execution."""
13
+
14
+ code: str
15
+ provider_name: str
16
+ variant_id: str
17
+ tokens: int
18
+ elapsed_time: float
19
+ quality_score: float = 0.0
20
+
21
+
22
+ class ParallelExecutor:
23
+ """Execute multiple provider calls in parallel."""
24
+
25
+ @staticmethod
26
+ async def execute_all(
27
+ variants: list[dict[str, Any]],
28
+ providers: list[Provider],
29
+ context: list[dict[str, Any]],
30
+ ) -> list[ProviderOutput]:
31
+ """
32
+ Execute variants across providers in parallel.
33
+
34
+ Args:
35
+ variants: List of variant prompts/parameters
36
+ providers: List of provider instances to use
37
+ context: Conversation context messages
38
+
39
+ Returns:
40
+ List of outputs from all executions
41
+ """
42
+ tasks = []
43
+
44
+ for i, variant in enumerate(variants):
45
+ # Round-robin across providers
46
+ provider = providers[i % len(providers)]
47
+ task = ParallelExecutor._execute_variant(
48
+ provider=provider,
49
+ variant=variant,
50
+ variant_id=f"v{i}",
51
+ context=context,
52
+ )
53
+ tasks.append(task)
54
+
55
+ results = await asyncio.gather(*tasks, return_exceptions=True)
56
+
57
+ # Filter out exceptions and return successful results
58
+ outputs: list[ProviderOutput] = []
59
+ for result in results:
60
+ if isinstance(result, Exception):
61
+ # Log error but continue
62
+ print(f"Variant execution failed: {result}")
63
+ continue
64
+ outputs.append(result) # type: ignore[arg-type]
65
+
66
+ return outputs
67
+
68
+ @staticmethod
69
+ async def _execute_variant(
70
+ provider: Provider,
71
+ variant: dict[str, Any],
72
+ variant_id: str,
73
+ context: list[dict[str, Any]],
74
+ ) -> ProviderOutput:
75
+ """Execute a single variant."""
76
+ import time
77
+
78
+ start_time = time.time()
79
+ tokens_used = 0
80
+ generated_text = []
81
+
82
+ # Build messages with variant prompt
83
+ messages = context + [{"role": "user", "content": variant["prompt"]}]
84
+
85
+ # Stream from provider
86
+ async for event in provider.stream( # type: ignore[attr-defined]
87
+ messages,
88
+ temperature=variant.get("temperature", 0.8),
89
+ top_p=variant.get("top_p", 0.95),
90
+ ):
91
+ if event.type == "text":
92
+ generated_text.append(event.data["text"])
93
+ elif event.type == "usage":
94
+ tokens_used = event.data.get("usage", {}).get("total_tokens", 0)
95
+
96
+ elapsed = time.time() - start_time
97
+
98
+ return ProviderOutput(
99
+ code="".join(generated_text),
100
+ provider_name=provider.__class__.__name__,
101
+ variant_id=variant_id,
102
+ tokens=tokens_used,
103
+ elapsed_time=elapsed,
104
+ )