superqode 0.1.5__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.
- superqode/__init__.py +33 -0
- superqode/acp/__init__.py +23 -0
- superqode/acp/client.py +913 -0
- superqode/acp/permission_screen.py +457 -0
- superqode/acp/types.py +480 -0
- superqode/acp_discovery.py +856 -0
- superqode/agent/__init__.py +22 -0
- superqode/agent/edit_strategies.py +334 -0
- superqode/agent/loop.py +892 -0
- superqode/agent/qe_report_templates.py +39 -0
- superqode/agent/system_prompts.py +353 -0
- superqode/agent_output.py +721 -0
- superqode/agent_stream.py +953 -0
- superqode/agents/__init__.py +59 -0
- superqode/agents/acp_registry.py +305 -0
- superqode/agents/client.py +249 -0
- superqode/agents/data/augmentcode.com.toml +51 -0
- superqode/agents/data/cagent.dev.toml +51 -0
- superqode/agents/data/claude.com.toml +60 -0
- superqode/agents/data/codeassistant.dev.toml +51 -0
- superqode/agents/data/codex.openai.com.toml +57 -0
- superqode/agents/data/fastagent.ai.toml +66 -0
- superqode/agents/data/geminicli.com.toml +77 -0
- superqode/agents/data/goose.block.xyz.toml +54 -0
- superqode/agents/data/junie.jetbrains.com.toml +56 -0
- superqode/agents/data/kimi.moonshot.cn.toml +57 -0
- superqode/agents/data/llmlingagent.dev.toml +51 -0
- superqode/agents/data/molt.bot.toml +49 -0
- superqode/agents/data/opencode.ai.toml +60 -0
- superqode/agents/data/stakpak.dev.toml +51 -0
- superqode/agents/data/vtcode.dev.toml +51 -0
- superqode/agents/discovery.py +266 -0
- superqode/agents/messaging.py +160 -0
- superqode/agents/persona.py +166 -0
- superqode/agents/registry.py +421 -0
- superqode/agents/schema.py +72 -0
- superqode/agents/unified.py +367 -0
- superqode/app/__init__.py +111 -0
- superqode/app/constants.py +314 -0
- superqode/app/css.py +366 -0
- superqode/app/models.py +118 -0
- superqode/app/suggester.py +125 -0
- superqode/app/widgets.py +1591 -0
- superqode/app_enhanced.py +399 -0
- superqode/app_main.py +17187 -0
- superqode/approval.py +312 -0
- superqode/atomic.py +296 -0
- superqode/commands/__init__.py +1 -0
- superqode/commands/acp.py +965 -0
- superqode/commands/agents.py +180 -0
- superqode/commands/auth.py +278 -0
- superqode/commands/config.py +374 -0
- superqode/commands/init.py +826 -0
- superqode/commands/providers.py +819 -0
- superqode/commands/qe.py +1145 -0
- superqode/commands/roles.py +380 -0
- superqode/commands/serve.py +172 -0
- superqode/commands/suggestions.py +127 -0
- superqode/commands/superqe.py +460 -0
- superqode/config/__init__.py +51 -0
- superqode/config/loader.py +812 -0
- superqode/config/schema.py +498 -0
- superqode/core/__init__.py +111 -0
- superqode/core/roles.py +281 -0
- superqode/danger.py +386 -0
- superqode/data/superqode-template.yaml +1522 -0
- superqode/design_system.py +1080 -0
- superqode/dialogs/__init__.py +6 -0
- superqode/dialogs/base.py +39 -0
- superqode/dialogs/model.py +130 -0
- superqode/dialogs/provider.py +870 -0
- superqode/diff_view.py +919 -0
- superqode/enterprise.py +21 -0
- superqode/evaluation/__init__.py +25 -0
- superqode/evaluation/adapters.py +93 -0
- superqode/evaluation/behaviors.py +89 -0
- superqode/evaluation/engine.py +209 -0
- superqode/evaluation/scenarios.py +96 -0
- superqode/execution/__init__.py +36 -0
- superqode/execution/linter.py +538 -0
- superqode/execution/modes.py +347 -0
- superqode/execution/resolver.py +283 -0
- superqode/execution/runner.py +642 -0
- superqode/file_explorer.py +811 -0
- superqode/file_viewer.py +471 -0
- superqode/flash.py +183 -0
- superqode/guidance/__init__.py +58 -0
- superqode/guidance/config.py +203 -0
- superqode/guidance/prompts.py +71 -0
- superqode/harness/__init__.py +54 -0
- superqode/harness/accelerator.py +291 -0
- superqode/harness/config.py +319 -0
- superqode/harness/validator.py +147 -0
- superqode/history.py +279 -0
- superqode/integrations/superopt_runner.py +124 -0
- superqode/logging/__init__.py +49 -0
- superqode/logging/adapters.py +219 -0
- superqode/logging/formatter.py +923 -0
- superqode/logging/integration.py +341 -0
- superqode/logging/sinks.py +170 -0
- superqode/logging/unified_log.py +417 -0
- superqode/lsp/__init__.py +26 -0
- superqode/lsp/client.py +544 -0
- superqode/main.py +1069 -0
- superqode/mcp/__init__.py +89 -0
- superqode/mcp/auth_storage.py +380 -0
- superqode/mcp/client.py +1236 -0
- superqode/mcp/config.py +319 -0
- superqode/mcp/integration.py +337 -0
- superqode/mcp/oauth.py +436 -0
- superqode/mcp/oauth_callback.py +385 -0
- superqode/mcp/types.py +290 -0
- superqode/memory/__init__.py +31 -0
- superqode/memory/feedback.py +342 -0
- superqode/memory/store.py +522 -0
- superqode/notifications.py +369 -0
- superqode/optimization/__init__.py +5 -0
- superqode/optimization/config.py +33 -0
- superqode/permissions/__init__.py +25 -0
- superqode/permissions/rules.py +488 -0
- superqode/plan.py +323 -0
- superqode/providers/__init__.py +33 -0
- superqode/providers/gateway/__init__.py +165 -0
- superqode/providers/gateway/base.py +228 -0
- superqode/providers/gateway/litellm_gateway.py +1170 -0
- superqode/providers/gateway/openresponses_gateway.py +436 -0
- superqode/providers/health.py +297 -0
- superqode/providers/huggingface/__init__.py +74 -0
- superqode/providers/huggingface/downloader.py +472 -0
- superqode/providers/huggingface/endpoints.py +442 -0
- superqode/providers/huggingface/hub.py +531 -0
- superqode/providers/huggingface/inference.py +394 -0
- superqode/providers/huggingface/transformers_runner.py +516 -0
- superqode/providers/local/__init__.py +100 -0
- superqode/providers/local/base.py +438 -0
- superqode/providers/local/discovery.py +418 -0
- superqode/providers/local/lmstudio.py +256 -0
- superqode/providers/local/mlx.py +457 -0
- superqode/providers/local/ollama.py +486 -0
- superqode/providers/local/sglang.py +268 -0
- superqode/providers/local/tgi.py +260 -0
- superqode/providers/local/tool_support.py +477 -0
- superqode/providers/local/vllm.py +258 -0
- superqode/providers/manager.py +1338 -0
- superqode/providers/models.py +1016 -0
- superqode/providers/models_dev.py +578 -0
- superqode/providers/openresponses/__init__.py +87 -0
- superqode/providers/openresponses/converters/__init__.py +17 -0
- superqode/providers/openresponses/converters/messages.py +343 -0
- superqode/providers/openresponses/converters/tools.py +268 -0
- superqode/providers/openresponses/schema/__init__.py +56 -0
- superqode/providers/openresponses/schema/models.py +585 -0
- superqode/providers/openresponses/streaming/__init__.py +5 -0
- superqode/providers/openresponses/streaming/parser.py +338 -0
- superqode/providers/openresponses/tools/__init__.py +21 -0
- superqode/providers/openresponses/tools/apply_patch.py +352 -0
- superqode/providers/openresponses/tools/code_interpreter.py +290 -0
- superqode/providers/openresponses/tools/file_search.py +333 -0
- superqode/providers/openresponses/tools/mcp_adapter.py +252 -0
- superqode/providers/registry.py +716 -0
- superqode/providers/usage.py +332 -0
- superqode/pure_mode.py +384 -0
- superqode/qr/__init__.py +23 -0
- superqode/qr/dashboard.py +781 -0
- superqode/qr/generator.py +1018 -0
- superqode/qr/templates.py +135 -0
- superqode/safety/__init__.py +41 -0
- superqode/safety/sandbox.py +413 -0
- superqode/safety/warnings.py +256 -0
- superqode/server/__init__.py +33 -0
- superqode/server/lsp_server.py +775 -0
- superqode/server/web.py +250 -0
- superqode/session/__init__.py +25 -0
- superqode/session/persistence.py +580 -0
- superqode/session/sharing.py +477 -0
- superqode/session.py +475 -0
- superqode/sidebar.py +2991 -0
- superqode/stream_view.py +648 -0
- superqode/styles/__init__.py +3 -0
- superqode/superqe/__init__.py +184 -0
- superqode/superqe/acp_runner.py +1064 -0
- superqode/superqe/constitution/__init__.py +62 -0
- superqode/superqe/constitution/evaluator.py +308 -0
- superqode/superqe/constitution/loader.py +432 -0
- superqode/superqe/constitution/schema.py +250 -0
- superqode/superqe/events.py +591 -0
- superqode/superqe/frameworks/__init__.py +65 -0
- superqode/superqe/frameworks/base.py +234 -0
- superqode/superqe/frameworks/e2e.py +263 -0
- superqode/superqe/frameworks/executor.py +237 -0
- superqode/superqe/frameworks/javascript.py +409 -0
- superqode/superqe/frameworks/python.py +373 -0
- superqode/superqe/frameworks/registry.py +92 -0
- superqode/superqe/mcp_tools/__init__.py +47 -0
- superqode/superqe/mcp_tools/core_tools.py +418 -0
- superqode/superqe/mcp_tools/registry.py +230 -0
- superqode/superqe/mcp_tools/testing_tools.py +167 -0
- superqode/superqe/noise.py +89 -0
- superqode/superqe/orchestrator.py +778 -0
- superqode/superqe/roles.py +609 -0
- superqode/superqe/session.py +713 -0
- superqode/superqe/skills/__init__.py +57 -0
- superqode/superqe/skills/base.py +106 -0
- superqode/superqe/skills/core_skills.py +899 -0
- superqode/superqe/skills/registry.py +90 -0
- superqode/superqe/verifier.py +101 -0
- superqode/superqe_cli.py +76 -0
- superqode/tool_call.py +358 -0
- superqode/tools/__init__.py +93 -0
- superqode/tools/agent_tools.py +496 -0
- superqode/tools/base.py +324 -0
- superqode/tools/batch_tool.py +133 -0
- superqode/tools/diagnostics.py +311 -0
- superqode/tools/edit_tools.py +653 -0
- superqode/tools/enhanced_base.py +515 -0
- superqode/tools/file_tools.py +269 -0
- superqode/tools/file_tracking.py +45 -0
- superqode/tools/lsp_tools.py +610 -0
- superqode/tools/network_tools.py +350 -0
- superqode/tools/permissions.py +400 -0
- superqode/tools/question_tool.py +324 -0
- superqode/tools/search_tools.py +598 -0
- superqode/tools/shell_tools.py +259 -0
- superqode/tools/todo_tools.py +121 -0
- superqode/tools/validation.py +80 -0
- superqode/tools/web_tools.py +639 -0
- superqode/tui.py +1152 -0
- superqode/tui_integration.py +875 -0
- superqode/tui_widgets/__init__.py +27 -0
- superqode/tui_widgets/widgets/__init__.py +18 -0
- superqode/tui_widgets/widgets/progress.py +185 -0
- superqode/tui_widgets/widgets/tool_display.py +188 -0
- superqode/undo_manager.py +574 -0
- superqode/utils/__init__.py +5 -0
- superqode/utils/error_handling.py +323 -0
- superqode/utils/fuzzy.py +257 -0
- superqode/widgets/__init__.py +477 -0
- superqode/widgets/agent_collab.py +390 -0
- superqode/widgets/agent_store.py +936 -0
- superqode/widgets/agent_switcher.py +395 -0
- superqode/widgets/animation_manager.py +284 -0
- superqode/widgets/code_context.py +356 -0
- superqode/widgets/command_palette.py +412 -0
- superqode/widgets/connection_status.py +537 -0
- superqode/widgets/conversation_history.py +470 -0
- superqode/widgets/diff_indicator.py +155 -0
- superqode/widgets/enhanced_status_bar.py +385 -0
- superqode/widgets/enhanced_toast.py +476 -0
- superqode/widgets/file_browser.py +809 -0
- superqode/widgets/file_reference.py +585 -0
- superqode/widgets/issue_timeline.py +340 -0
- superqode/widgets/leader_key.py +264 -0
- superqode/widgets/mode_switcher.py +445 -0
- superqode/widgets/model_picker.py +234 -0
- superqode/widgets/permission_preview.py +1205 -0
- superqode/widgets/prompt.py +358 -0
- superqode/widgets/provider_connect.py +725 -0
- superqode/widgets/pty_shell.py +587 -0
- superqode/widgets/qe_dashboard.py +321 -0
- superqode/widgets/resizable_sidebar.py +377 -0
- superqode/widgets/response_changes.py +218 -0
- superqode/widgets/response_display.py +528 -0
- superqode/widgets/rich_tool_display.py +613 -0
- superqode/widgets/sidebar_panels.py +1180 -0
- superqode/widgets/slash_complete.py +356 -0
- superqode/widgets/split_view.py +612 -0
- superqode/widgets/status_bar.py +273 -0
- superqode/widgets/superqode_display.py +786 -0
- superqode/widgets/thinking_display.py +815 -0
- superqode/widgets/throbber.py +87 -0
- superqode/widgets/toast.py +206 -0
- superqode/widgets/unified_output.py +1073 -0
- superqode/workspace/__init__.py +75 -0
- superqode/workspace/artifacts.py +472 -0
- superqode/workspace/coordinator.py +353 -0
- superqode/workspace/diff_tracker.py +429 -0
- superqode/workspace/git_guard.py +373 -0
- superqode/workspace/git_snapshot.py +526 -0
- superqode/workspace/manager.py +750 -0
- superqode/workspace/snapshot.py +357 -0
- superqode/workspace/watcher.py +535 -0
- superqode/workspace/worktree.py +440 -0
- superqode-0.1.5.dist-info/METADATA +204 -0
- superqode-0.1.5.dist-info/RECORD +288 -0
- superqode-0.1.5.dist-info/WHEEL +5 -0
- superqode-0.1.5.dist-info/entry_points.txt +3 -0
- superqode-0.1.5.dist-info/licenses/LICENSE +648 -0
- superqode-0.1.5.dist-info/top_level.txt +1 -0
superqode/enterprise.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Enterprise feature gating for SuperQode OSS."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
_console = Console()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def require_enterprise(feature_name: str) -> bool:
|
|
12
|
+
"""Check if enterprise features are available."""
|
|
13
|
+
try:
|
|
14
|
+
import superqode_enterprise # noqa: F401
|
|
15
|
+
except Exception:
|
|
16
|
+
_console.print(
|
|
17
|
+
f"[yellow]{feature_name} is available in SuperQode Enterprise.[/yellow]\n"
|
|
18
|
+
"[dim]Install the enterprise package to enable this feature.[/dim]"
|
|
19
|
+
)
|
|
20
|
+
return False
|
|
21
|
+
return True
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Enhanced evaluation capabilities with CodeOptiX integration."""
|
|
2
|
+
|
|
3
|
+
# Import CodeOptiX modules as normal dependencies
|
|
4
|
+
try:
|
|
5
|
+
from codeoptix.evaluation import EvaluationEngine as CodeOptiXEngine
|
|
6
|
+
from codeoptix.behaviors import create_behavior
|
|
7
|
+
from codeoptix.evaluation.bloom_integration import BloomIdeationIntegration
|
|
8
|
+
from codeoptix.evolution import EvolutionEngine as CodeOptiXEvolutionEngine
|
|
9
|
+
|
|
10
|
+
CODEOPTIX_AVAILABLE = True
|
|
11
|
+
except ImportError:
|
|
12
|
+
CODEOPTIX_AVAILABLE = False
|
|
13
|
+
CodeOptiXEngine = None
|
|
14
|
+
create_behavior = None
|
|
15
|
+
BloomIdeationIntegration = None
|
|
16
|
+
CodeOptiXEvolutionEngine = None
|
|
17
|
+
|
|
18
|
+
# Export what's available
|
|
19
|
+
__all__ = [
|
|
20
|
+
"CODEOPTIX_AVAILABLE",
|
|
21
|
+
"CodeOptiXEngine",
|
|
22
|
+
"create_behavior",
|
|
23
|
+
"BloomIdeationIntegration",
|
|
24
|
+
"CodeOptiXEvolutionEngine",
|
|
25
|
+
]
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""Agent adapters for CodeOptiX integration."""
|
|
2
|
+
|
|
3
|
+
from typing import Dict, Any, Optional
|
|
4
|
+
import logging
|
|
5
|
+
|
|
6
|
+
from superqode.evaluation import CODEOPTIX_AVAILABLE
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SuperQodeCodeOptiXAdapter:
|
|
12
|
+
"""Adapter to connect SuperQode agents with CodeOptiX evaluation."""
|
|
13
|
+
|
|
14
|
+
def __init__(self):
|
|
15
|
+
"""Initialize the adapter."""
|
|
16
|
+
self.codeoptix_adapter = None
|
|
17
|
+
|
|
18
|
+
if CODEOPTIX_AVAILABLE:
|
|
19
|
+
try:
|
|
20
|
+
from codeoptix.adapters.factory import create_adapter
|
|
21
|
+
|
|
22
|
+
self.create_adapter = create_adapter
|
|
23
|
+
self.codeoptix_adapter = create_adapter("basic") # Default adapter
|
|
24
|
+
except Exception as e:
|
|
25
|
+
logger.warning(f"CodeOptiX adapter creation failed: {e}")
|
|
26
|
+
|
|
27
|
+
def create_agent_adapter(self, agent_config: Dict[str, Any]):
|
|
28
|
+
"""Create a CodeOptiX adapter for a specific agent configuration."""
|
|
29
|
+
if not self.codeoptix_adapter:
|
|
30
|
+
return None
|
|
31
|
+
|
|
32
|
+
try:
|
|
33
|
+
agent_type = agent_config.get("type", "basic")
|
|
34
|
+
|
|
35
|
+
# Map SuperQode agent types to CodeOptiX adapter types
|
|
36
|
+
adapter_mapping = {
|
|
37
|
+
"claude-code": "claude-code",
|
|
38
|
+
"codex": "codex",
|
|
39
|
+
"gemini-cli": "gemini-cli",
|
|
40
|
+
"basic": "basic",
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
codeoptix_type = adapter_mapping.get(agent_type, "basic")
|
|
44
|
+
|
|
45
|
+
adapter = self.create_adapter(codeoptix_type, agent_config)
|
|
46
|
+
logger.info(f"Created CodeOptiX adapter for {agent_type}")
|
|
47
|
+
return adapter
|
|
48
|
+
|
|
49
|
+
except Exception as e:
|
|
50
|
+
logger.error(f"Failed to create agent adapter: {e}")
|
|
51
|
+
return None
|
|
52
|
+
|
|
53
|
+
def adapt_agent_output(self, agent_output: Any) -> Optional[Dict[str, Any]]:
|
|
54
|
+
"""Adapt SuperQode agent output to CodeOptiX format."""
|
|
55
|
+
if not agent_output:
|
|
56
|
+
return None
|
|
57
|
+
|
|
58
|
+
try:
|
|
59
|
+
# Convert SuperQode output format to CodeOptiX expected format
|
|
60
|
+
adapted = {
|
|
61
|
+
"content": getattr(agent_output, "content", str(agent_output)),
|
|
62
|
+
"metadata": getattr(agent_output, "metadata", {}),
|
|
63
|
+
"success": getattr(agent_output, "success", True),
|
|
64
|
+
"timestamp": getattr(agent_output, "timestamp", None),
|
|
65
|
+
}
|
|
66
|
+
return adapted
|
|
67
|
+
|
|
68
|
+
except Exception as e:
|
|
69
|
+
logger.error(f"Agent output adaptation failed: {e}")
|
|
70
|
+
return None
|
|
71
|
+
|
|
72
|
+
def is_adapter_available(self) -> bool:
|
|
73
|
+
"""Check if CodeOptiX adapter is available."""
|
|
74
|
+
return self.codeoptix_adapter is not None
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# Global adapter instance
|
|
78
|
+
adapter_manager = SuperQodeCodeOptiXAdapter()
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def get_codeoptix_adapter(agent_config: Dict[str, Any]):
|
|
82
|
+
"""Get a CodeOptiX adapter for the given agent configuration."""
|
|
83
|
+
return adapter_manager.create_agent_adapter(agent_config)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def adapt_agent_output_for_evaluation(agent_output: Any) -> Optional[Dict[str, Any]]:
|
|
87
|
+
"""Adapt agent output for CodeOptiX evaluation."""
|
|
88
|
+
return adapter_manager.adapt_agent_output(agent_output)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def is_codeoptix_integration_available() -> bool:
|
|
92
|
+
"""Check if CodeOptiX integration is available."""
|
|
93
|
+
return adapter_manager.is_adapter_available()
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""Enhanced behaviors for quality evaluation using CodeOptiX."""
|
|
2
|
+
|
|
3
|
+
from typing import Dict, Any, List
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from superqode.evaluation import CODEOPTIX_AVAILABLE
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class EnhancedBehaviorManager:
|
|
10
|
+
"""Manager for enhanced evaluation behaviors."""
|
|
11
|
+
|
|
12
|
+
def __init__(self):
|
|
13
|
+
"""Initialize behavior manager."""
|
|
14
|
+
self._behaviors = {}
|
|
15
|
+
|
|
16
|
+
if CODEOPTIX_AVAILABLE:
|
|
17
|
+
self._load_codeoptix_behaviors()
|
|
18
|
+
|
|
19
|
+
def _load_codeoptix_behaviors(self):
|
|
20
|
+
"""Load CodeOptiX behaviors."""
|
|
21
|
+
try:
|
|
22
|
+
from codeoptix.behaviors import insecure_code, vacuous_tests, plan_drift
|
|
23
|
+
|
|
24
|
+
self._behaviors.update(
|
|
25
|
+
{
|
|
26
|
+
"security-vulnerabilities": insecure_code.InsecureCodeBehavior(),
|
|
27
|
+
"test-quality": vacuous_tests.VacuousTestsBehavior(),
|
|
28
|
+
"plan-adherence": plan_drift.PlanDriftBehavior(),
|
|
29
|
+
}
|
|
30
|
+
)
|
|
31
|
+
except ImportError:
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
def get_behavior(self, name: str):
|
|
35
|
+
"""Get a behavior by name."""
|
|
36
|
+
return self._behaviors.get(name)
|
|
37
|
+
|
|
38
|
+
def list_behaviors(self) -> Dict[str, str]:
|
|
39
|
+
"""List all available behaviors with descriptions."""
|
|
40
|
+
descriptions = {
|
|
41
|
+
"security-vulnerabilities": "Detects hardcoded secrets, SQL injection, XSS vulnerabilities",
|
|
42
|
+
"test-quality": "Evaluates test completeness, assertion quality, and coverage",
|
|
43
|
+
"plan-adherence": "Checks if implementation matches requirements and plans",
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
# Only return behaviors that are actually available
|
|
47
|
+
available = {}
|
|
48
|
+
for name, behavior in self._behaviors.items():
|
|
49
|
+
if behavior is not None:
|
|
50
|
+
available[name] = descriptions.get(name, f"Enhanced {name} analysis")
|
|
51
|
+
|
|
52
|
+
return available
|
|
53
|
+
|
|
54
|
+
def evaluate_behavior(
|
|
55
|
+
self, behavior_name: str, codebase_path: Path, config: Dict[str, Any]
|
|
56
|
+
) -> Dict[str, Any]:
|
|
57
|
+
"""Evaluate a specific behavior on the codebase."""
|
|
58
|
+
behavior = self.get_behavior(behavior_name)
|
|
59
|
+
if not behavior:
|
|
60
|
+
return {"error": f"Behavior {behavior_name} not available"}
|
|
61
|
+
|
|
62
|
+
try:
|
|
63
|
+
# This is a simplified interface - in practice, you'd need to
|
|
64
|
+
# adapt the behavior to work with the codebase
|
|
65
|
+
return {
|
|
66
|
+
"behavior": behavior_name,
|
|
67
|
+
"status": "completed",
|
|
68
|
+
"findings": [], # Would contain actual findings
|
|
69
|
+
"score": 0.85, # Example quality score
|
|
70
|
+
"details": f"Evaluated {behavior_name} on {codebase_path}",
|
|
71
|
+
}
|
|
72
|
+
except Exception as e:
|
|
73
|
+
return {"error": f"Evaluation failed: {str(e)}"}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# Global behavior manager instance
|
|
77
|
+
behavior_manager = EnhancedBehaviorManager()
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def get_enhanced_behaviors() -> Dict[str, str]:
|
|
81
|
+
"""Get available enhanced behaviors."""
|
|
82
|
+
return behavior_manager.list_behaviors()
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def evaluate_enhanced_behavior(
|
|
86
|
+
behavior_name: str, codebase_path: Path, config: Dict[str, Any]
|
|
87
|
+
) -> Dict[str, Any]:
|
|
88
|
+
"""Evaluate an enhanced behavior."""
|
|
89
|
+
return behavior_manager.evaluate_behavior(behavior_name, codebase_path, config)
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"""Enhanced evaluation engine integrating CodeOptiX capabilities."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Dict, Any, List, Optional
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
from superqode.evaluation import (
|
|
8
|
+
CODEOPTIX_AVAILABLE,
|
|
9
|
+
CodeOptiXEngine,
|
|
10
|
+
create_behavior,
|
|
11
|
+
BloomIdeationIntegration,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
# Import CodeOptiX utilities if available
|
|
15
|
+
try:
|
|
16
|
+
from codeoptix.utils.llm import create_llm_client, LLMProvider
|
|
17
|
+
from codeoptix.adapters.factory import create_adapter
|
|
18
|
+
except ImportError:
|
|
19
|
+
create_llm_client = None
|
|
20
|
+
LLMProvider = None
|
|
21
|
+
create_adapter = None
|
|
22
|
+
|
|
23
|
+
logger = logging.getLogger(__name__)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class EnhancedQEEngine:
|
|
27
|
+
"""Enhanced Quality Engineering engine with CodeOptiX integration."""
|
|
28
|
+
|
|
29
|
+
def __init__(self):
|
|
30
|
+
"""Initialize the enhanced QE engine."""
|
|
31
|
+
self.codeoptix_engine = None
|
|
32
|
+
self.bloom_generator = None
|
|
33
|
+
|
|
34
|
+
if CODEOPTIX_AVAILABLE and create_llm_client and create_adapter:
|
|
35
|
+
try:
|
|
36
|
+
# Try to create LLM client (try all available providers)
|
|
37
|
+
llm_client = None
|
|
38
|
+
import os
|
|
39
|
+
|
|
40
|
+
# Provider priority: Ollama (free) -> OpenAI -> Anthropic -> Google
|
|
41
|
+
provider_configs = [
|
|
42
|
+
(LLMProvider.OLLAMA, None, "llama3.1"),
|
|
43
|
+
(LLMProvider.OPENAI, os.getenv("OPENAI_API_KEY"), None),
|
|
44
|
+
(LLMProvider.ANTHROPIC, os.getenv("ANTHROPIC_API_KEY"), None),
|
|
45
|
+
(LLMProvider.GOOGLE, os.getenv("GOOGLE_API_KEY"), None),
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
for provider, api_key, model in provider_configs:
|
|
49
|
+
try:
|
|
50
|
+
if provider == LLMProvider.OLLAMA or api_key:
|
|
51
|
+
llm_client = create_llm_client(provider, api_key=api_key, model=model)
|
|
52
|
+
break # Successfully created client
|
|
53
|
+
except Exception:
|
|
54
|
+
continue # Try next provider
|
|
55
|
+
|
|
56
|
+
if llm_client:
|
|
57
|
+
# Create basic adapter for testing/development
|
|
58
|
+
# BasicAdapter needs llm_config to create its own llm_client
|
|
59
|
+
adapter_config = {
|
|
60
|
+
"llm_config": {
|
|
61
|
+
"provider": "ollama", # Default to ollama
|
|
62
|
+
"model": "llama3.1",
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
adapter = create_adapter("basic", adapter_config)
|
|
66
|
+
|
|
67
|
+
# Initialize CodeOptiX evaluation engine
|
|
68
|
+
# Note: we're passing llm_client to EvaluationEngine, but BasicAdapter creates its own
|
|
69
|
+
# This might work if they're compatible
|
|
70
|
+
self.codeoptix_engine = CodeOptiXEngine(
|
|
71
|
+
adapter=adapter,
|
|
72
|
+
llm_client=llm_client,
|
|
73
|
+
config={"scenario_generator": {"use_bloom": True}},
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# Initialize Bloom generator with the same llm_client
|
|
77
|
+
self.bloom_generator = BloomIdeationIntegration(llm_client=llm_client)
|
|
78
|
+
|
|
79
|
+
# Initialize enhanced behaviors
|
|
80
|
+
self.enhanced_behaviors = {
|
|
81
|
+
"security-vulnerabilities": self._create_security_behavior(),
|
|
82
|
+
"test-quality": self._create_test_behavior(),
|
|
83
|
+
"plan-adherence": self._create_plan_behavior(),
|
|
84
|
+
}
|
|
85
|
+
else:
|
|
86
|
+
logger.warning("No LLM client available for CodeOptiX evaluation")
|
|
87
|
+
self.enhanced_behaviors = {}
|
|
88
|
+
except Exception as e:
|
|
89
|
+
logger.error(f"Failed to initialize CodeOptiX engine: {e}")
|
|
90
|
+
self.enhanced_behaviors = {}
|
|
91
|
+
else:
|
|
92
|
+
self.enhanced_behaviors = {}
|
|
93
|
+
|
|
94
|
+
def _create_security_behavior(self):
|
|
95
|
+
"""Create security vulnerability behavior."""
|
|
96
|
+
if CODEOPTIX_AVAILABLE and create_behavior:
|
|
97
|
+
return create_behavior("insecure-code")
|
|
98
|
+
return None
|
|
99
|
+
|
|
100
|
+
def _create_test_behavior(self):
|
|
101
|
+
"""Create test quality behavior."""
|
|
102
|
+
if CODEOPTIX_AVAILABLE and create_behavior:
|
|
103
|
+
return create_behavior("vacuous-tests")
|
|
104
|
+
return None
|
|
105
|
+
|
|
106
|
+
def _create_plan_behavior(self):
|
|
107
|
+
"""Create plan adherence behavior."""
|
|
108
|
+
if CODEOPTIX_AVAILABLE and create_behavior:
|
|
109
|
+
return create_behavior("plan-drift")
|
|
110
|
+
return None
|
|
111
|
+
|
|
112
|
+
def analyze_with_codeoptix(
|
|
113
|
+
self, codebase_path: Path, config: Dict[str, Any], behaviors: Optional[List[str]] = None
|
|
114
|
+
) -> Dict[str, Any]:
|
|
115
|
+
"""Perform enhanced analysis using CodeOptiX capabilities."""
|
|
116
|
+
if not CODEOPTIX_AVAILABLE or not self.codeoptix_engine:
|
|
117
|
+
return {"error": "CodeOptiX evaluation engine not available"}
|
|
118
|
+
|
|
119
|
+
try:
|
|
120
|
+
# Determine which behaviors to run
|
|
121
|
+
if behaviors is None:
|
|
122
|
+
behaviors = ["insecure-code", "vacuous-tests"] # Use CodeOptiX behavior names
|
|
123
|
+
|
|
124
|
+
# Map SuperQode behavior names to CodeOptiX behavior names
|
|
125
|
+
behavior_mapping = {
|
|
126
|
+
"security-vulnerabilities": "insecure-code",
|
|
127
|
+
"test-quality": "vacuous-tests",
|
|
128
|
+
"plan-adherence": "plan-drift",
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
# Convert to CodeOptiX behavior names
|
|
132
|
+
codeoptix_behaviors = []
|
|
133
|
+
for behavior in behaviors:
|
|
134
|
+
codeoptix_name = behavior_mapping.get(behavior, behavior)
|
|
135
|
+
codeoptix_behaviors.append(codeoptix_name)
|
|
136
|
+
|
|
137
|
+
# Generate scenarios if requested
|
|
138
|
+
scenarios = None
|
|
139
|
+
if config.get("use_bloom_scenarios", False) and self.bloom_generator:
|
|
140
|
+
try:
|
|
141
|
+
scenarios = self.bloom_generator.generate_scenarios(
|
|
142
|
+
behavior_name="comprehensive-quality",
|
|
143
|
+
behavior_description="Multi-dimensional code quality evaluation",
|
|
144
|
+
examples=config.get("scenario_examples", []),
|
|
145
|
+
)
|
|
146
|
+
except Exception as e:
|
|
147
|
+
logger.warning(f"Bloom scenario generation failed: {e}")
|
|
148
|
+
|
|
149
|
+
# Run CodeOptiX evaluation
|
|
150
|
+
try:
|
|
151
|
+
results = self.codeoptix_engine.evaluate_behaviors(
|
|
152
|
+
behavior_names=codeoptix_behaviors,
|
|
153
|
+
scenarios=scenarios,
|
|
154
|
+
context={"codebase_path": str(codebase_path)},
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
"enhanced_analysis": True,
|
|
159
|
+
"behaviors_evaluated": behaviors,
|
|
160
|
+
"results": results,
|
|
161
|
+
"scenarios_used": len(scenarios) if scenarios else 0,
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
except Exception as e:
|
|
165
|
+
error_msg = str(e)
|
|
166
|
+
# Provide cleaner error messages for common issues
|
|
167
|
+
if "Ollama" in error_msg and ("daemon" in error_msg or "contact" in error_msg):
|
|
168
|
+
clean_error = "LLM provider not available. Configure one of: Ollama (ollama serve), OpenAI (OPENAI_API_KEY), Anthropic (ANTHROPIC_API_KEY), or Google (GOOGLE_API_KEY)"
|
|
169
|
+
else:
|
|
170
|
+
clean_error = f"CodeOptiX evaluation failed: {error_msg}"
|
|
171
|
+
logger.error(clean_error)
|
|
172
|
+
|
|
173
|
+
return {"error": clean_error, "enhanced_analysis": False}
|
|
174
|
+
|
|
175
|
+
except Exception as e:
|
|
176
|
+
logger.error(f"Enhanced CodeOptiX analysis failed: {e}")
|
|
177
|
+
return {"error": f"Enhanced analysis failed: {str(e)}", "enhanced_analysis": False}
|
|
178
|
+
|
|
179
|
+
def get_available_behaviors(self) -> Dict[str, str]:
|
|
180
|
+
"""Get all available behaviors (basic + enhanced)."""
|
|
181
|
+
behaviors = {
|
|
182
|
+
# Basic behaviors (always available)
|
|
183
|
+
"syntax-errors": "Basic syntax validation",
|
|
184
|
+
"code-style": "PEP8 and style checking",
|
|
185
|
+
"imports": "Import organization and dependencies",
|
|
186
|
+
"documentation": "Documentation completeness",
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
# Add enhanced behaviors if available
|
|
190
|
+
if CODEOPTIX_AVAILABLE:
|
|
191
|
+
behaviors.update(
|
|
192
|
+
{
|
|
193
|
+
"security-vulnerabilities": "Advanced security analysis (CodeOptiX)",
|
|
194
|
+
"test-quality": "Intelligent test evaluation (CodeOptiX)",
|
|
195
|
+
"plan-adherence": "Requirements alignment checking (CodeOptiX)",
|
|
196
|
+
}
|
|
197
|
+
)
|
|
198
|
+
else:
|
|
199
|
+
behaviors["codeoptix-integration"] = (
|
|
200
|
+
"CodeOptiX integration is available (codeoptix dependency required)."
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
return behaviors
|
|
204
|
+
|
|
205
|
+
def is_behavior_available(self, behavior_name: str) -> bool:
|
|
206
|
+
"""Check if a specific behavior is available."""
|
|
207
|
+
if behavior_name in self.enhanced_behaviors:
|
|
208
|
+
return self.enhanced_behaviors[behavior_name] is not None
|
|
209
|
+
return behavior_name in ["syntax-errors", "code-style", "imports", "documentation"]
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"""Bloom scenario generation integration for enhanced testing."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Dict, Any, List, Optional
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
from superqode.evaluation import CODEOPTIX_AVAILABLE, BloomIdeationIntegration
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class EnhancedScenarioGenerator:
|
|
13
|
+
"""Enhanced scenario generator using Bloom ideation."""
|
|
14
|
+
|
|
15
|
+
def __init__(self):
|
|
16
|
+
"""Initialize the scenario generator."""
|
|
17
|
+
self.bloom_generator = None
|
|
18
|
+
|
|
19
|
+
if CODEOPTIX_AVAILABLE:
|
|
20
|
+
try:
|
|
21
|
+
self.bloom_generator = BloomIdeationIntegration()
|
|
22
|
+
except Exception as e:
|
|
23
|
+
logger.warning(f"Bloom integration failed: {e}")
|
|
24
|
+
|
|
25
|
+
def generate_bloom_scenarios(
|
|
26
|
+
self,
|
|
27
|
+
behavior_name: str,
|
|
28
|
+
behavior_description: str,
|
|
29
|
+
codebase_path: Path,
|
|
30
|
+
examples: Optional[List[Dict[str, Any]]] = None,
|
|
31
|
+
) -> List[Dict[str, Any]]:
|
|
32
|
+
"""Generate intelligent test scenarios using Bloom."""
|
|
33
|
+
if not self.bloom_generator:
|
|
34
|
+
logger.info("Bloom generator not available, using basic scenarios")
|
|
35
|
+
return self._generate_basic_scenarios(behavior_name, codebase_path)
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
scenarios = self.bloom_generator.generate_scenarios(
|
|
39
|
+
behavior_name=behavior_name,
|
|
40
|
+
behavior_description=behavior_description,
|
|
41
|
+
examples=examples or [],
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
logger.info(f"Generated {len(scenarios)} Bloom scenarios for {behavior_name}")
|
|
45
|
+
return scenarios
|
|
46
|
+
|
|
47
|
+
except Exception as e:
|
|
48
|
+
logger.error(f"Bloom scenario generation failed: {e}")
|
|
49
|
+
return self._generate_basic_scenarios(behavior_name, codebase_path)
|
|
50
|
+
|
|
51
|
+
def _generate_basic_scenarios(
|
|
52
|
+
self, behavior_name: str, codebase_path: Path
|
|
53
|
+
) -> List[Dict[str, Any]]:
|
|
54
|
+
"""Generate basic fallback scenarios."""
|
|
55
|
+
# Basic scenarios as fallback when Bloom is not available
|
|
56
|
+
base_scenarios = [
|
|
57
|
+
{
|
|
58
|
+
"name": f"basic-{behavior_name}-scenario-1",
|
|
59
|
+
"description": f"Basic scenario for {behavior_name}",
|
|
60
|
+
"complexity": "low",
|
|
61
|
+
"tags": ["basic", behavior_name],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"name": f"basic-{behavior_name}-scenario-2",
|
|
65
|
+
"description": f"Alternative scenario for {behavior_name}",
|
|
66
|
+
"complexity": "medium",
|
|
67
|
+
"tags": ["basic", "alternative", behavior_name],
|
|
68
|
+
},
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
logger.info(f"Generated {len(base_scenarios)} basic scenarios as fallback")
|
|
72
|
+
return base_scenarios
|
|
73
|
+
|
|
74
|
+
def is_bloom_available(self) -> bool:
|
|
75
|
+
"""Check if Bloom scenario generation is available."""
|
|
76
|
+
return self.bloom_generator is not None
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# Global scenario generator instance
|
|
80
|
+
scenario_generator = EnhancedScenarioGenerator()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def generate_enhanced_scenarios(
|
|
84
|
+
behavior_name: str,
|
|
85
|
+
behavior_description: str,
|
|
86
|
+
codebase_path: Path,
|
|
87
|
+
examples: Optional[List[Dict[str, Any]]] = None,
|
|
88
|
+
use_bloom: bool = True,
|
|
89
|
+
) -> List[Dict[str, Any]]:
|
|
90
|
+
"""Generate enhanced scenarios with optional Bloom integration."""
|
|
91
|
+
if use_bloom and scenario_generator.is_bloom_available():
|
|
92
|
+
return scenario_generator.generate_bloom_scenarios(
|
|
93
|
+
behavior_name, behavior_description, codebase_path, examples
|
|
94
|
+
)
|
|
95
|
+
else:
|
|
96
|
+
return scenario_generator._generate_basic_scenarios(behavior_name, codebase_path)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Execution module - Hard-constrained test execution roles.
|
|
3
|
+
|
|
4
|
+
These are "dumb runners" that execute existing tests without
|
|
5
|
+
discovery, inference, or generation.
|
|
6
|
+
|
|
7
|
+
Roles:
|
|
8
|
+
- Smoke Tester: Runs smoke tests, fail-fast, no discovery
|
|
9
|
+
- Sanity Tester: Runs sanity tests, verifies recent changes
|
|
10
|
+
- Regression Tester: Runs full regression suite, detects flakes
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from .runner import (
|
|
14
|
+
TestRunner,
|
|
15
|
+
SmokeRunner,
|
|
16
|
+
SanityRunner,
|
|
17
|
+
RegressionRunner,
|
|
18
|
+
TestResult,
|
|
19
|
+
TestSuiteResult,
|
|
20
|
+
)
|
|
21
|
+
from .linter import LinterRunner, LinterRunResult
|
|
22
|
+
from .modes import ExecutionMode, QuickScanConfig, DeepQEConfig
|
|
23
|
+
|
|
24
|
+
__all__ = [
|
|
25
|
+
"TestRunner",
|
|
26
|
+
"SmokeRunner",
|
|
27
|
+
"SanityRunner",
|
|
28
|
+
"RegressionRunner",
|
|
29
|
+
"TestResult",
|
|
30
|
+
"TestSuiteResult",
|
|
31
|
+
"LinterRunner",
|
|
32
|
+
"LinterRunResult",
|
|
33
|
+
"ExecutionMode",
|
|
34
|
+
"QuickScanConfig",
|
|
35
|
+
"DeepQEConfig",
|
|
36
|
+
]
|