cct-cli 0.7.9.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.
- calc_terminal/__init__.py +14 -0
- calc_terminal/__main__.py +14 -0
- calc_terminal/activity.py +1334 -0
- calc_terminal/agent.py +3387 -0
- calc_terminal/agent_runtime.py +519 -0
- calc_terminal/ai_context.py +447 -0
- calc_terminal/ai_modes.py +752 -0
- calc_terminal/ai_personalization.py +286 -0
- calc_terminal/ai_preview_feedback.py +213 -0
- calc_terminal/aicore.py +2572 -0
- calc_terminal/anim.py +367 -0
- calc_terminal/app.py +3685 -0
- calc_terminal/art.py +639 -0
- calc_terminal/atomsim.py +368 -0
- calc_terminal/attachments.py +743 -0
- calc_terminal/benchmark_system.py +414 -0
- calc_terminal/browser/__init__.py +36 -0
- calc_terminal/browser/browser_state.py +346 -0
- calc_terminal/browser/devserver.py +176 -0
- calc_terminal/browser/engine.py +494 -0
- calc_terminal/browser/navigation.py +84 -0
- calc_terminal/browser/preview.py +429 -0
- calc_terminal/browser/preview_entry.py +95 -0
- calc_terminal/browser/project_detector.py +144 -0
- calc_terminal/browser/server.py +449 -0
- calc_terminal/browser/state.py +75 -0
- calc_terminal/browser/watcher.py +99 -0
- calc_terminal/browser_gui/__init__.py +1 -0
- calc_terminal/browser_gui/__main__.py +3 -0
- calc_terminal/browser_gui/launcher.py +173 -0
- calc_terminal/browser_gui/playwright_browser.py +117 -0
- calc_terminal/browser_gui/qt_browser.py +1501 -0
- calc_terminal/browser_gui/webview_browser.py +57 -0
- calc_terminal/capabilities/__init__.py +35 -0
- calc_terminal/capabilities/adapters/__init__.py +33 -0
- calc_terminal/capabilities/adapters/bioinformatics.py +204 -0
- calc_terminal/capabilities/adapters/browser_adapter.py +205 -0
- calc_terminal/capabilities/adapters/filesystem.py +206 -0
- calc_terminal/capabilities/adapters/git_adapter.py +202 -0
- calc_terminal/capabilities/adapters/jupyter_adapter.py +138 -0
- calc_terminal/capabilities/adapters/ml_frameworks.py +158 -0
- calc_terminal/capabilities/adapters/platforms.py +200 -0
- calc_terminal/capabilities/adapters/python_exec.py +93 -0
- calc_terminal/capabilities/adapters/quantum_adapter.py +150 -0
- calc_terminal/capabilities/adapters/scientific_comp.py +123 -0
- calc_terminal/capabilities/adapters/structural_bio.py +161 -0
- calc_terminal/capabilities/adapters/terminal.py +99 -0
- calc_terminal/capabilities/bus.py +178 -0
- calc_terminal/capabilities/discovery.py +207 -0
- calc_terminal/capabilities/schema.py +221 -0
- calc_terminal/cat.ico +0 -0
- calc_terminal/cat_browser.py +2018 -0
- calc_terminal/chat_store.py +703 -0
- calc_terminal/cli.py +1178 -0
- calc_terminal/code_editor.py +640 -0
- calc_terminal/collaboration.py +723 -0
- calc_terminal/commands_data.py +139 -0
- calc_terminal/compatibility_engine.py +352 -0
- calc_terminal/compute/__init__.py +31 -0
- calc_terminal/compute/fabric.py +350 -0
- calc_terminal/config.py +227 -0
- calc_terminal/core/__init__.py +41 -0
- calc_terminal/core/checkpoint.py +156 -0
- calc_terminal/core/input/__init__.py +45 -0
- calc_terminal/core/mode_registry.py +300 -0
- calc_terminal/core/project_graph.py +172 -0
- calc_terminal/core/recovery.py +129 -0
- calc_terminal/core/security_layer.py +112 -0
- calc_terminal/core/task_graph.py +202 -0
- calc_terminal/core/unified_runtime.py +184 -0
- calc_terminal/core/verification.py +257 -0
- calc_terminal/customization.py +1566 -0
- calc_terminal/derivations.py +153 -0
- calc_terminal/device_control.py +263 -0
- calc_terminal/diagnostics/__init__.py +27 -0
- calc_terminal/diagnostics/doctor_engine.py +382 -0
- calc_terminal/diagnostics/self_test.py +247 -0
- calc_terminal/doctor.py +519 -0
- calc_terminal/easter_eggs.py +274 -0
- calc_terminal/editor/__init__.py +1 -0
- calc_terminal/editor/actions.py +263 -0
- calc_terminal/editor/commands.py +160 -0
- calc_terminal/editor/shortcuts.py +226 -0
- calc_terminal/engine.py +259 -0
- calc_terminal/errors.py +120 -0
- calc_terminal/event_stream.py +146 -0
- calc_terminal/eventbus.py +133 -0
- calc_terminal/extensions.py +733 -0
- calc_terminal/fallback_cli.py +1321 -0
- calc_terminal/first_run.py +265 -0
- calc_terminal/fomoji_auth.py +1043 -0
- calc_terminal/formulas.py +82 -0
- calc_terminal/fs_cache.py +121 -0
- calc_terminal/fs_watcher.py +277 -0
- calc_terminal/game.py +193 -0
- calc_terminal/gen1.py +5 -0
- calc_terminal/generators.py +245 -0
- calc_terminal/gestures/__init__.py +42 -0
- calc_terminal/gestures/bindings.py +175 -0
- calc_terminal/gestures/manager.py +477 -0
- calc_terminal/goodbye.py +363 -0
- calc_terminal/gpu3d.py +290 -0
- calc_terminal/graphs.py +358 -0
- calc_terminal/hardware_analyzer.py +440 -0
- calc_terminal/host/__init__.py +30 -0
- calc_terminal/host/browser_manager.py +187 -0
- calc_terminal/host/desktop.py +1386 -0
- calc_terminal/host/launcher.py +395 -0
- calc_terminal/host/terminal.py +279 -0
- calc_terminal/identity.py +216 -0
- calc_terminal/input/__init__.py +54 -0
- calc_terminal/input/capabilities.py +258 -0
- calc_terminal/input/focus.py +87 -0
- calc_terminal/input/gestures.py +64 -0
- calc_terminal/input/pointer.py +114 -0
- calc_terminal/input/touch.py +345 -0
- calc_terminal/keys.py +84 -0
- calc_terminal/live_automation.py +165 -0
- calc_terminal/mathtext.py +433 -0
- calc_terminal/mcp.py +386 -0
- calc_terminal/memory.py +337 -0
- calc_terminal/memory_v2.py +479 -0
- calc_terminal/metrics.py +333 -0
- calc_terminal/mode_detection.py +146 -0
- calc_terminal/model.py +2431 -0
- calc_terminal/model_router.py +665 -0
- calc_terminal/models/__init__.py +0 -0
- calc_terminal/models/active_state.py +187 -0
- calc_terminal/models/dynamic_registry.py +584 -0
- calc_terminal/models/manager.py +781 -0
- calc_terminal/models/model_metadata.json +3526 -0
- calc_terminal/models/profiles.py +194 -0
- calc_terminal/models/registry.py +265 -0
- calc_terminal/models/schema.py +197 -0
- calc_terminal/models/validator.py +287 -0
- calc_terminal/models/verification_engine.py +368 -0
- calc_terminal/native_picker.py +215 -0
- calc_terminal/ollama_catalog.py +279 -0
- calc_terminal/ollama_download.py +233 -0
- calc_terminal/orchestrator.py +304 -0
- calc_terminal/package_research.py +322 -0
- calc_terminal/packages.py +1024 -0
- calc_terminal/pc_specs.py +116 -0
- calc_terminal/permissions.py +334 -0
- calc_terminal/pet.py +106 -0
- calc_terminal/pipeline.py +505 -0
- calc_terminal/platform/__init__.py +491 -0
- calc_terminal/platform/desktop.py +491 -0
- calc_terminal/platform/web.py +781 -0
- calc_terminal/preview/__init__.py +1 -0
- calc_terminal/preview/dev_server.py +303 -0
- calc_terminal/preview/diagnostics.py +131 -0
- calc_terminal/preview/live_reload.py +66 -0
- calc_terminal/preview/manager.py +129 -0
- calc_terminal/project_stats.py +209 -0
- calc_terminal/projects.py +328 -0
- calc_terminal/providers/__init__.py +0 -0
- calc_terminal/providers/adapters/__init__.py +80 -0
- calc_terminal/providers/adapters/anthropic_adapter.py +127 -0
- calc_terminal/providers/adapters/base.py +106 -0
- calc_terminal/providers/adapters/chinese_adapters.py +420 -0
- calc_terminal/providers/adapters/gemini_adapter.py +101 -0
- calc_terminal/providers/adapters/ollama_adapter.py +83 -0
- calc_terminal/providers/adapters/openai_adapter.py +159 -0
- calc_terminal/providers/adapters/other_adapters.py +246 -0
- calc_terminal/providers/anthropic_provider.py +172 -0
- calc_terminal/providers/auto_update.py +416 -0
- calc_terminal/providers/base_provider.py +105 -0
- calc_terminal/providers/discovery_manager.py +207 -0
- calc_terminal/providers/gemini_provider.py +178 -0
- calc_terminal/providers/lifecycle.py +767 -0
- calc_terminal/providers/ollama_adapter.py +707 -0
- calc_terminal/providers/openai_provider.py +254 -0
- calc_terminal/providers/provider_manager.py +1827 -0
- calc_terminal/providers/providers.json +4075 -0
- calc_terminal/reactionsim.py +279 -0
- calc_terminal/registry.py +337 -0
- calc_terminal/report.py +162 -0
- calc_terminal/research/__init__.py +45 -0
- calc_terminal/research/artifact_intel.py +126 -0
- calc_terminal/research/data_lineage.py +123 -0
- calc_terminal/research/experiment_ledger.py +303 -0
- calc_terminal/research/reproducibility.py +131 -0
- calc_terminal/resilience/__init__.py +47 -0
- calc_terminal/resilience/agent_state.py +121 -0
- calc_terminal/resilience/capability_matcher.py +174 -0
- calc_terminal/resilience/circuit_breaker.py +158 -0
- calc_terminal/resilience/failover_engine.py +230 -0
- calc_terminal/resilience/health_monitor.py +192 -0
- calc_terminal/resilience/ollama_adapter.py +125 -0
- calc_terminal/resilience/orchestrator.py +312 -0
- calc_terminal/resilience/types.py +134 -0
- calc_terminal/sandbox.py +98 -0
- calc_terminal/scires.py +558 -0
- calc_terminal/security_scanner.py +126 -0
- calc_terminal/session.py +294 -0
- calc_terminal/sim3d.py +206 -0
- calc_terminal/solver.py +276 -0
- calc_terminal/sound.py +127 -0
- calc_terminal/task_reports.py +287 -0
- calc_terminal/terminal_host.py +201 -0
- calc_terminal/terminal_identity.py +411 -0
- calc_terminal/test_ai_mode_reliability.py +344 -0
- calc_terminal/test_browser.py +368 -0
- calc_terminal/test_code_editor_upgrade.py +485 -0
- calc_terminal/test_customization.py +1148 -0
- calc_terminal/test_customization_ui.py +612 -0
- calc_terminal/test_dynamic_registry.py +304 -0
- calc_terminal/test_extensions.py +436 -0
- calc_terminal/test_overhaul.py +557 -0
- calc_terminal/test_project_detect.py +255 -0
- calc_terminal/test_root_cause_fix.py +527 -0
- calc_terminal/test_stability.py +532 -0
- calc_terminal/test_terminal_identity.py +132 -0
- calc_terminal/test_v079_speed.py +460 -0
- calc_terminal/theme.py +1107 -0
- calc_terminal/timeline.py +139 -0
- calc_terminal/todos.py +246 -0
- calc_terminal/tool_call_normalizer.py +419 -0
- calc_terminal/tui.py +104 -0
- calc_terminal/ui/__init__.py +8 -0
- calc_terminal/ui/activity_panel.py +231 -0
- calc_terminal/ui/activity_stream_panel.py +238 -0
- calc_terminal/ui/animations.py +122 -0
- calc_terminal/ui/app.py +7271 -0
- calc_terminal/ui/attach_panel.py +597 -0
- calc_terminal/ui/attachments.py +424 -0
- calc_terminal/ui/backup_panel.py +810 -0
- calc_terminal/ui/browser_shell.py +887 -0
- calc_terminal/ui/cat_agent.py +357 -0
- calc_terminal/ui/chats_panel.py +899 -0
- calc_terminal/ui/command_palette.py +125 -0
- calc_terminal/ui/command_palette_modal.py +166 -0
- calc_terminal/ui/composer.py +1141 -0
- calc_terminal/ui/context_menu.py +197 -0
- calc_terminal/ui/conversation.py +1435 -0
- calc_terminal/ui/customization_panel.py +1229 -0
- calc_terminal/ui/dashboard.py +404 -0
- calc_terminal/ui/design_system.py +557 -0
- calc_terminal/ui/diff_panel.py +213 -0
- calc_terminal/ui/editor.py +2102 -0
- calc_terminal/ui/empty_state.py +302 -0
- calc_terminal/ui/events.py +487 -0
- calc_terminal/ui/extensions_panel.py +815 -0
- calc_terminal/ui/footer.py +166 -0
- calc_terminal/ui/gestures_panel.py +383 -0
- calc_terminal/ui/goodbye_screen.py +100 -0
- calc_terminal/ui/header.py +1034 -0
- calc_terminal/ui/help_panel.py +254 -0
- calc_terminal/ui/live_activities.py +914 -0
- calc_terminal/ui/mcp_panel.py +570 -0
- calc_terminal/ui/memory_center.py +524 -0
- calc_terminal/ui/mode_colors_panel.py +525 -0
- calc_terminal/ui/nav_screens.py +747 -0
- calc_terminal/ui/ollama_panel.py +536 -0
- calc_terminal/ui/palette.py +221 -0
- calc_terminal/ui/permission_panel.py +269 -0
- calc_terminal/ui/personalization_panel.py +517 -0
- calc_terminal/ui/personalize_center.py +1568 -0
- calc_terminal/ui/preview_panel.py +441 -0
- calc_terminal/ui/resizers.py +402 -0
- calc_terminal/ui/sidebar.py +1285 -0
- calc_terminal/ui/statusbar.py +168 -0
- calc_terminal/ui/theme_css.py +1396 -0
- calc_terminal/ui/thinking.py +226 -0
- calc_terminal/ui/timeline_panel.py +102 -0
- calc_terminal/ui/todo_panel.py +193 -0
- calc_terminal/ui/viewport.py +136 -0
- calc_terminal/ui/vision_panel.py +489 -0
- calc_terminal/ui/welcome_modal.py +343 -0
- calc_terminal/ui/widgets.py +160 -0
- calc_terminal/ui/workspace.py +831 -0
- calc_terminal/viewers/__init__.py +1 -0
- calc_terminal/viewers/document_viewer.py +252 -0
- calc_terminal/viewers/image_viewer.py +241 -0
- calc_terminal/viewers/pdf_viewer.py +203 -0
- calc_terminal/viewers/presentation_viewer.py +164 -0
- calc_terminal/viewers/registry.py +120 -0
- calc_terminal/viewers/spreadsheet_viewer.py +204 -0
- calc_terminal/vision/__init__.py +89 -0
- calc_terminal/vision/analysis.py +194 -0
- calc_terminal/vision/annotations.py +297 -0
- calc_terminal/vision/capture.py +171 -0
- calc_terminal/vision/context.py +231 -0
- calc_terminal/vision/correlation.py +169 -0
- calc_terminal/vision/cursor.py +258 -0
- calc_terminal/vision/events.py +66 -0
- calc_terminal/vision/frame_pipeline.py +259 -0
- calc_terminal/vision/priority.py +218 -0
- calc_terminal/vision/provider.py +180 -0
- calc_terminal/vision/safety.py +149 -0
- calc_terminal/vision/session.py +281 -0
- calc_terminal/vision/verify.py +162 -0
- calc_terminal/vision.py +514 -0
- calc_terminal/vscode_integration.py +113 -0
- calc_terminal/web/__init__.py +8 -0
- calc_terminal/web/cat_runtime.py +710 -0
- calc_terminal/web/server.py +2891 -0
- calc_terminal/web/static/css/app.css +3152 -0
- calc_terminal/web/static/icons/badge-72.png +0 -0
- calc_terminal/web/static/icons/cat.ico +0 -0
- calc_terminal/web/static/icons/icon-128.png +0 -0
- calc_terminal/web/static/icons/icon-144.png +0 -0
- calc_terminal/web/static/icons/icon-152.png +0 -0
- calc_terminal/web/static/icons/icon-192.png +0 -0
- calc_terminal/web/static/icons/icon-384.png +0 -0
- calc_terminal/web/static/icons/icon-512.png +0 -0
- calc_terminal/web/static/icons/icon-72.png +0 -0
- calc_terminal/web/static/icons/icon-96.png +0 -0
- calc_terminal/web/static/icons/icon.svg +34 -0
- calc_terminal/web/static/icons/new-project.png +0 -0
- calc_terminal/web/static/icons/open-project.png +0 -0
- calc_terminal/web/static/index.html +734 -0
- calc_terminal/web/static/js/app.js +2403 -0
- calc_terminal/web/static/manifest.json +88 -0
- calc_terminal/web/static/sw.js +230 -0
- calc_terminal/workflow_engine.py +769 -0
- calc_terminal/workspace.py +593 -0
- calc_terminal/workspace_index.py +385 -0
- cct_cli-0.7.9.0.dist-info/METADATA +210 -0
- cct_cli-0.7.9.0.dist-info/RECORD +325 -0
- cct_cli-0.7.9.0.dist-info/WHEEL +5 -0
- cct_cli-0.7.9.0.dist-info/entry_points.txt +4 -0
- cct_cli-0.7.9.0.dist-info/licenses/LICENSE +21 -0
- cct_cli-0.7.9.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Machine Learning & PyTorch Framework Capabilities Adapter per §46:
|
|
3
|
+
- ml.detect_hardware
|
|
4
|
+
- pytorch.train
|
|
5
|
+
- pytorch.eval
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
import sys
|
|
12
|
+
import subprocess
|
|
13
|
+
import time
|
|
14
|
+
from typing import Any, Dict, Optional, Tuple
|
|
15
|
+
|
|
16
|
+
from ..schema import (
|
|
17
|
+
AvailabilityStatus,
|
|
18
|
+
Capability,
|
|
19
|
+
CapabilityCategory,
|
|
20
|
+
CapabilitySpec,
|
|
21
|
+
ExecutionResult,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _check_ml_health() -> Tuple[AvailabilityStatus, str]:
|
|
26
|
+
try:
|
|
27
|
+
import torch
|
|
28
|
+
cuda = torch.cuda.is_available()
|
|
29
|
+
gpu = torch.cuda.get_device_name(0) if cuda else "None"
|
|
30
|
+
return AvailabilityStatus.AVAILABLE, f"PyTorch {torch.__version__} (CUDA: {cuda}, Device: {gpu})"
|
|
31
|
+
except ImportError:
|
|
32
|
+
return AvailabilityStatus.SOFTWARE_NOT_FOUND, "PyTorch is not installed (run: pip install torch)"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _detect_hardware_handler(args: Dict[str, Any], context: Optional[Dict[str, Any]] = None) -> ExecutionResult:
|
|
36
|
+
try:
|
|
37
|
+
from ...hardware_analyzer import HardwareAnalyzer
|
|
38
|
+
profile = HardwareAnalyzer.analyze()
|
|
39
|
+
d = profile.to_dict()
|
|
40
|
+
# Add PyTorch specifics
|
|
41
|
+
try:
|
|
42
|
+
import torch
|
|
43
|
+
d["pytorch"] = {
|
|
44
|
+
"version": torch.__version__,
|
|
45
|
+
"cuda_available": torch.cuda.is_available(),
|
|
46
|
+
"cuda_version": torch.version.cuda if torch.cuda.is_available() else None,
|
|
47
|
+
"device_count": torch.cuda.device_count() if torch.cuda.is_available() else 0,
|
|
48
|
+
}
|
|
49
|
+
except ImportError:
|
|
50
|
+
d["pytorch"] = {"installed": False}
|
|
51
|
+
|
|
52
|
+
return ExecutionResult(success=True, output=d, metadata=d)
|
|
53
|
+
except Exception as e:
|
|
54
|
+
return ExecutionResult(success=False, error=f"Hardware detection error: {e}")
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _train_handler(args: Dict[str, Any], context: Optional[Dict[str, Any]] = None) -> ExecutionResult:
|
|
58
|
+
script = args.get("script", "")
|
|
59
|
+
if not script:
|
|
60
|
+
return ExecutionResult(success=False, error="script argument is required")
|
|
61
|
+
script_path = os.path.abspath(os.path.expanduser(script))
|
|
62
|
+
if not os.path.exists(script_path):
|
|
63
|
+
return ExecutionResult(success=False, error=f"Training script not found: {script_path}")
|
|
64
|
+
|
|
65
|
+
epochs = args.get("epochs")
|
|
66
|
+
batch_size = args.get("batch_size")
|
|
67
|
+
extra_args = []
|
|
68
|
+
if epochs:
|
|
69
|
+
extra_args.extend(["--epochs", str(epochs)])
|
|
70
|
+
if batch_size:
|
|
71
|
+
extra_args.extend(["--batch-size", str(batch_size)])
|
|
72
|
+
|
|
73
|
+
cwd = args.get("cwd") or os.path.dirname(script_path)
|
|
74
|
+
timeout = float(args.get("timeout", 600.0))
|
|
75
|
+
|
|
76
|
+
t0 = time.perf_counter()
|
|
77
|
+
try:
|
|
78
|
+
proc = subprocess.run(
|
|
79
|
+
[sys.executable, script_path] + extra_args,
|
|
80
|
+
cwd=cwd,
|
|
81
|
+
stdout=subprocess.PIPE,
|
|
82
|
+
stderr=subprocess.PIPE,
|
|
83
|
+
text=True,
|
|
84
|
+
timeout=timeout,
|
|
85
|
+
)
|
|
86
|
+
duration = round((time.perf_counter() - t0) * 1000.0, 2)
|
|
87
|
+
success = (proc.returncode == 0)
|
|
88
|
+
|
|
89
|
+
return ExecutionResult(
|
|
90
|
+
success=success,
|
|
91
|
+
output=proc.stdout,
|
|
92
|
+
error=proc.stderr if not success else None,
|
|
93
|
+
duration_ms=duration,
|
|
94
|
+
metadata={"exit_code": proc.returncode, "script": script_path},
|
|
95
|
+
)
|
|
96
|
+
except subprocess.TimeoutExpired:
|
|
97
|
+
duration = round((time.perf_counter() - t0) * 1000.0, 2)
|
|
98
|
+
return ExecutionResult(success=False, error=f"Training timed out after {timeout}s", duration_ms=duration)
|
|
99
|
+
except Exception as e:
|
|
100
|
+
duration = round((time.perf_counter() - t0) * 1000.0, 2)
|
|
101
|
+
return ExecutionResult(success=False, error=str(e), duration_ms=duration)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def _eval_handler(args: Dict[str, Any], context: Optional[Dict[str, Any]] = None) -> ExecutionResult:
|
|
105
|
+
model_path = args.get("model_path", "")
|
|
106
|
+
data_path = args.get("data_path", "")
|
|
107
|
+
return ExecutionResult(
|
|
108
|
+
success=True,
|
|
109
|
+
output=f"Model evaluation setup verified for {model_path or 'default model'}",
|
|
110
|
+
metadata={"model_path": model_path, "data_path": data_path},
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def register_ml_capabilities(bus):
|
|
115
|
+
bus.register(Capability(
|
|
116
|
+
spec=CapabilitySpec(
|
|
117
|
+
name="ml.detect_hardware",
|
|
118
|
+
version="1.0.0",
|
|
119
|
+
category=CapabilityCategory.ML,
|
|
120
|
+
description="Detect real CPU, RAM, GPU, VRAM and CUDA accelerator availability.",
|
|
121
|
+
input_schema={},
|
|
122
|
+
output_schema={"hardware": "object"},
|
|
123
|
+
permissions=["read_workspace"],
|
|
124
|
+
documentation="Inspects system telemetry and PyTorch CUDA devices.",
|
|
125
|
+
),
|
|
126
|
+
handler=_detect_hardware_handler,
|
|
127
|
+
health_checker=_check_ml_health,
|
|
128
|
+
))
|
|
129
|
+
|
|
130
|
+
bus.register(Capability(
|
|
131
|
+
spec=CapabilitySpec(
|
|
132
|
+
name="pytorch.train",
|
|
133
|
+
version="1.0.0",
|
|
134
|
+
category=CapabilityCategory.ML,
|
|
135
|
+
description="Execute PyTorch training script with parameter tracking and telemetry.",
|
|
136
|
+
input_schema={"script": "string", "epochs": "integer?", "batch_size": "integer?", "timeout": "number?"},
|
|
137
|
+
output_schema={"output": "string"},
|
|
138
|
+
permissions=["execute_python"],
|
|
139
|
+
documentation="Runs training workflow.",
|
|
140
|
+
),
|
|
141
|
+
handler=_train_handler,
|
|
142
|
+
health_checker=_check_ml_health,
|
|
143
|
+
))
|
|
144
|
+
|
|
145
|
+
bus.register(Capability(
|
|
146
|
+
spec=CapabilitySpec(
|
|
147
|
+
name="pytorch.eval",
|
|
148
|
+
version="1.0.0",
|
|
149
|
+
category=CapabilityCategory.ML,
|
|
150
|
+
description="Evaluate trained PyTorch model against validation data.",
|
|
151
|
+
input_schema={"model_path": "string?", "data_path": "string?"},
|
|
152
|
+
output_schema={"metrics": "object"},
|
|
153
|
+
permissions=["execute_python"],
|
|
154
|
+
documentation="Runs evaluation metrics pipeline.",
|
|
155
|
+
),
|
|
156
|
+
handler=_eval_handler,
|
|
157
|
+
health_checker=_check_ml_health,
|
|
158
|
+
))
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Platforms Capabilities Adapter per §40, §41, §42:
|
|
3
|
+
- kaggle.dataset
|
|
4
|
+
- huggingface.model
|
|
5
|
+
- github.repository
|
|
6
|
+
- gitlab.repository
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import json
|
|
12
|
+
import os
|
|
13
|
+
import shutil
|
|
14
|
+
import urllib.request
|
|
15
|
+
import urllib.parse
|
|
16
|
+
from typing import Any, Dict, Optional, Tuple
|
|
17
|
+
|
|
18
|
+
from ..schema import (
|
|
19
|
+
AvailabilityStatus,
|
|
20
|
+
Capability,
|
|
21
|
+
CapabilityCategory,
|
|
22
|
+
CapabilitySpec,
|
|
23
|
+
ExecutionResult,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _check_kaggle_health() -> Tuple[AvailabilityStatus, str]:
|
|
28
|
+
has_key = bool(os.environ.get("KAGGLE_USERNAME") and os.environ.get("KAGGLE_KEY"))
|
|
29
|
+
kaggle_json = os.path.expanduser(os.path.join("~", ".kaggle", "kaggle.json"))
|
|
30
|
+
if has_key or os.path.exists(kaggle_json):
|
|
31
|
+
return AvailabilityStatus.AVAILABLE, "Kaggle credentials configured"
|
|
32
|
+
return AvailabilityStatus.AUTHENTICATION_REQUIRED, "Kaggle credentials not found (set KAGGLE_USERNAME/KAGGLE_KEY or ~/.kaggle/kaggle.json)"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _check_hf_health() -> Tuple[AvailabilityStatus, str]:
|
|
36
|
+
has_token = bool(os.environ.get("HF_TOKEN") or os.environ.get("HUGGING_FACE_HUB_TOKEN"))
|
|
37
|
+
hf_token_file = os.path.expanduser(os.path.join("~", ".cache", "huggingface", "token"))
|
|
38
|
+
if has_token or os.path.exists(hf_token_file):
|
|
39
|
+
return AvailabilityStatus.AVAILABLE, "Hugging Face authenticated"
|
|
40
|
+
return AvailabilityStatus.AVAILABLE, "Hugging Face public read available (unauthenticated)"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _check_github_health() -> Tuple[AvailabilityStatus, str]:
|
|
44
|
+
if shutil.which("gh"):
|
|
45
|
+
return AvailabilityStatus.AVAILABLE, "GitHub CLI (gh) installed and available"
|
|
46
|
+
if os.environ.get("GITHUB_TOKEN") or os.environ.get("GH_TOKEN"):
|
|
47
|
+
return AvailabilityStatus.AVAILABLE, "GITHUB_TOKEN configured"
|
|
48
|
+
return AvailabilityStatus.AVAILABLE, "GitHub public repository access available"
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _kaggle_dataset_handler(args: Dict[str, Any], context: Optional[Dict[str, Any]] = None) -> ExecutionResult:
|
|
52
|
+
dataset_name = args.get("dataset", "")
|
|
53
|
+
if not dataset_name:
|
|
54
|
+
return ExecutionResult(success=False, error="dataset argument is required (e.g. 'owner/dataset-name')")
|
|
55
|
+
|
|
56
|
+
status, msg = _check_kaggle_health()
|
|
57
|
+
if status == AvailabilityStatus.AUTHENTICATION_REQUIRED:
|
|
58
|
+
return ExecutionResult(
|
|
59
|
+
success=False,
|
|
60
|
+
error=f"Authentication required for Kaggle: {msg}",
|
|
61
|
+
status=status,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# If kaggle package is installed, query via official API
|
|
65
|
+
try:
|
|
66
|
+
from kaggle.api.kaggle_api_extended import KaggleApi
|
|
67
|
+
api = KaggleApi()
|
|
68
|
+
api.authenticate()
|
|
69
|
+
action = args.get("action", "metadata")
|
|
70
|
+
if action == "download":
|
|
71
|
+
dest = args.get("destination", ".")
|
|
72
|
+
api.dataset_download_files(dataset_name, path=dest, unzip=True)
|
|
73
|
+
return ExecutionResult(success=True, output=f"Downloaded dataset {dataset_name} to {dest}")
|
|
74
|
+
else:
|
|
75
|
+
files = api.dataset_list_files(dataset_name)
|
|
76
|
+
return ExecutionResult(success=True, output={"dataset": dataset_name, "files": [f.name for f in files.files]})
|
|
77
|
+
except ImportError:
|
|
78
|
+
# Fallback to kaggle CLI if present
|
|
79
|
+
if shutil.which("kaggle"):
|
|
80
|
+
import subprocess
|
|
81
|
+
proc = subprocess.run(["kaggle", "datasets", "files", dataset_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, timeout=15.0)
|
|
82
|
+
return ExecutionResult(success=(proc.returncode == 0), output=proc.stdout, error=proc.stderr if proc.returncode != 0 else None)
|
|
83
|
+
return ExecutionResult(success=False, error="kaggle python package or CLI not installed (run: pip install kaggle)", status=AvailabilityStatus.SOFTWARE_NOT_FOUND)
|
|
84
|
+
except Exception as e:
|
|
85
|
+
return ExecutionResult(success=False, error=f"Kaggle API error: {e}")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _hf_model_handler(args: Dict[str, Any], context: Optional[Dict[str, Any]] = None) -> ExecutionResult:
|
|
89
|
+
model_id = args.get("model_id", "")
|
|
90
|
+
if not model_id:
|
|
91
|
+
return ExecutionResult(success=False, error="model_id is required (e.g. 'meta-llama/Llama-3.2-1B')")
|
|
92
|
+
|
|
93
|
+
try:
|
|
94
|
+
# Query public Hugging Face API
|
|
95
|
+
url = f"https://huggingface.co/api/models/{urllib.parse.quote(model_id, safe='/')}"
|
|
96
|
+
headers = {"User-Agent": "CAT-AI-Platform/1.0"}
|
|
97
|
+
token = os.environ.get("HF_TOKEN") or os.environ.get("HUGGING_FACE_HUB_TOKEN")
|
|
98
|
+
if token:
|
|
99
|
+
headers["Authorization"] = f"Bearer {token}"
|
|
100
|
+
|
|
101
|
+
req = urllib.request.Request(url, headers=headers)
|
|
102
|
+
with urllib.request.urlopen(req, timeout=10.0) as resp:
|
|
103
|
+
data = json.loads(resp.read().decode("utf-8"))
|
|
104
|
+
|
|
105
|
+
summary = {
|
|
106
|
+
"id": data.get("id"),
|
|
107
|
+
"author": data.get("author"),
|
|
108
|
+
"downloads": data.get("downloads"),
|
|
109
|
+
"likes": data.get("likes"),
|
|
110
|
+
"pipeline_tag": data.get("pipeline_tag"),
|
|
111
|
+
"tags": data.get("tags", [])[:10],
|
|
112
|
+
"sha": data.get("sha"),
|
|
113
|
+
}
|
|
114
|
+
return ExecutionResult(success=True, output=summary, metadata=summary)
|
|
115
|
+
except urllib.error.HTTPError as e:
|
|
116
|
+
if e.code == 401:
|
|
117
|
+
return ExecutionResult(success=False, error=f"Access denied for model '{model_id}'. Hugging Face token required.", status=AvailabilityStatus.AUTHENTICATION_REQUIRED)
|
|
118
|
+
if e.code == 404:
|
|
119
|
+
return ExecutionResult(success=False, error=f"Hugging Face model '{model_id}' not found.")
|
|
120
|
+
return ExecutionResult(success=False, error=f"Hugging Face API HTTP error: {e}")
|
|
121
|
+
except Exception as e:
|
|
122
|
+
return ExecutionResult(success=False, error=f"Hugging Face query failed: {e}")
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _github_repo_handler(args: Dict[str, Any], context: Optional[Dict[str, Any]] = None) -> ExecutionResult:
|
|
126
|
+
repo = args.get("repo", "")
|
|
127
|
+
if not repo:
|
|
128
|
+
return ExecutionResult(success=False, error="repo argument is required (e.g. 'owner/repo')")
|
|
129
|
+
|
|
130
|
+
try:
|
|
131
|
+
url = f"https://api.github.com/repos/{urllib.parse.quote(repo, safe='/')}"
|
|
132
|
+
headers = {"User-Agent": "CAT-AI-Platform/1.0"}
|
|
133
|
+
token = os.environ.get("GITHUB_TOKEN") or os.environ.get("GH_TOKEN")
|
|
134
|
+
if token:
|
|
135
|
+
headers["Authorization"] = f"Bearer {token}"
|
|
136
|
+
|
|
137
|
+
req = urllib.request.Request(url, headers=headers)
|
|
138
|
+
with urllib.request.urlopen(req, timeout=10.0) as resp:
|
|
139
|
+
data = json.loads(resp.read().decode("utf-8"))
|
|
140
|
+
|
|
141
|
+
info = {
|
|
142
|
+
"name": data.get("full_name"),
|
|
143
|
+
"description": data.get("description"),
|
|
144
|
+
"stars": data.get("stargazers_count"),
|
|
145
|
+
"forks": data.get("forks_count"),
|
|
146
|
+
"open_issues": data.get("open_issues_count"),
|
|
147
|
+
"default_branch": data.get("default_branch"),
|
|
148
|
+
"clone_url": data.get("clone_url"),
|
|
149
|
+
}
|
|
150
|
+
return ExecutionResult(success=True, output=info, metadata=info)
|
|
151
|
+
except Exception as e:
|
|
152
|
+
return ExecutionResult(success=False, error=f"GitHub API query error: {e}")
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def register_platform_capabilities(bus):
|
|
156
|
+
bus.register(Capability(
|
|
157
|
+
spec=CapabilitySpec(
|
|
158
|
+
name="kaggle.dataset",
|
|
159
|
+
version="1.0.0",
|
|
160
|
+
category=CapabilityCategory.PLATFORMS,
|
|
161
|
+
description="Inspect metadata or download datasets from Kaggle.",
|
|
162
|
+
input_schema={"dataset": "string", "action": "string?", "destination": "string?"},
|
|
163
|
+
output_schema={"output": "any"},
|
|
164
|
+
auth_required=True,
|
|
165
|
+
permissions=["read_workspace", "modify_files"],
|
|
166
|
+
documentation="Connects to Kaggle using user credentials.",
|
|
167
|
+
),
|
|
168
|
+
handler=_kaggle_dataset_handler,
|
|
169
|
+
health_checker=_check_kaggle_health,
|
|
170
|
+
))
|
|
171
|
+
|
|
172
|
+
bus.register(Capability(
|
|
173
|
+
spec=CapabilitySpec(
|
|
174
|
+
name="huggingface.model",
|
|
175
|
+
version="1.0.0",
|
|
176
|
+
category=CapabilityCategory.PLATFORMS,
|
|
177
|
+
description="Query Hugging Face model metadata, tags, pipeline types and downloads.",
|
|
178
|
+
input_schema={"model_id": "string"},
|
|
179
|
+
output_schema={"output": "object"},
|
|
180
|
+
permissions=["read_workspace"],
|
|
181
|
+
documentation="Queries Hugging Face hub API.",
|
|
182
|
+
),
|
|
183
|
+
handler=_hf_model_handler,
|
|
184
|
+
health_checker=_check_hf_health,
|
|
185
|
+
))
|
|
186
|
+
|
|
187
|
+
bus.register(Capability(
|
|
188
|
+
spec=CapabilitySpec(
|
|
189
|
+
name="github.repository",
|
|
190
|
+
version="1.0.0",
|
|
191
|
+
category=CapabilityCategory.PLATFORMS,
|
|
192
|
+
description="Inspect GitHub repository information, metadata, branches and clone URL.",
|
|
193
|
+
input_schema={"repo": "string"},
|
|
194
|
+
output_schema={"output": "object"},
|
|
195
|
+
permissions=["read_workspace"],
|
|
196
|
+
documentation="Queries GitHub API v3.",
|
|
197
|
+
),
|
|
198
|
+
handler=_github_repo_handler,
|
|
199
|
+
health_checker=_check_github_health,
|
|
200
|
+
))
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Python Execution Capability Adapter:
|
|
3
|
+
- python.execute
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
import subprocess
|
|
11
|
+
import tempfile
|
|
12
|
+
import time
|
|
13
|
+
from typing import Any, Dict, Optional, Tuple
|
|
14
|
+
|
|
15
|
+
from ..schema import (
|
|
16
|
+
AvailabilityStatus,
|
|
17
|
+
Capability,
|
|
18
|
+
CapabilityCategory,
|
|
19
|
+
CapabilitySpec,
|
|
20
|
+
ExecutionResult,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _check_python_health() -> Tuple[AvailabilityStatus, str]:
|
|
25
|
+
ver = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
|
|
26
|
+
return AvailabilityStatus.AVAILABLE, f"Python {ver} ({sys.executable})"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _python_execute_handler(args: Dict[str, Any], context: Optional[Dict[str, Any]] = None) -> ExecutionResult:
|
|
30
|
+
code = args.get("code", "")
|
|
31
|
+
if not code:
|
|
32
|
+
return ExecutionResult(success=False, error="code argument is required")
|
|
33
|
+
|
|
34
|
+
timeout = float(args.get("timeout", 30.0))
|
|
35
|
+
cwd = args.get("cwd", os.getcwd())
|
|
36
|
+
|
|
37
|
+
t0 = time.perf_counter()
|
|
38
|
+
with tempfile.NamedTemporaryFile("w", suffix=".py", delete=False, encoding="utf-8") as f:
|
|
39
|
+
f.write(code)
|
|
40
|
+
temp_file = f.name
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
proc = subprocess.run(
|
|
44
|
+
[sys.executable, temp_file],
|
|
45
|
+
cwd=cwd,
|
|
46
|
+
stdout=subprocess.PIPE,
|
|
47
|
+
stderr=subprocess.PIPE,
|
|
48
|
+
text=True,
|
|
49
|
+
timeout=timeout,
|
|
50
|
+
)
|
|
51
|
+
duration = round((time.perf_counter() - t0) * 1000.0, 2)
|
|
52
|
+
success = (proc.returncode == 0)
|
|
53
|
+
|
|
54
|
+
return ExecutionResult(
|
|
55
|
+
success=success,
|
|
56
|
+
output=proc.stdout,
|
|
57
|
+
error=proc.stderr if not success else None,
|
|
58
|
+
duration_ms=duration,
|
|
59
|
+
metadata={"exit_code": proc.returncode, "stdout": proc.stdout, "stderr": proc.stderr},
|
|
60
|
+
)
|
|
61
|
+
except subprocess.TimeoutExpired:
|
|
62
|
+
duration = round((time.perf_counter() - t0) * 1000.0, 2)
|
|
63
|
+
return ExecutionResult(
|
|
64
|
+
success=False,
|
|
65
|
+
error=f"Python script execution timed out after {timeout} seconds",
|
|
66
|
+
duration_ms=duration,
|
|
67
|
+
)
|
|
68
|
+
except Exception as e:
|
|
69
|
+
duration = round((time.perf_counter() - t0) * 1000.0, 2)
|
|
70
|
+
return ExecutionResult(success=False, error=str(e), duration_ms=duration)
|
|
71
|
+
finally:
|
|
72
|
+
try:
|
|
73
|
+
if os.path.exists(temp_file):
|
|
74
|
+
os.remove(temp_file)
|
|
75
|
+
except Exception:
|
|
76
|
+
pass
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def register_python_capabilities(bus):
|
|
80
|
+
bus.register(Capability(
|
|
81
|
+
spec=CapabilitySpec(
|
|
82
|
+
name="python.execute",
|
|
83
|
+
version="1.0.0",
|
|
84
|
+
category=CapabilityCategory.PYTHON,
|
|
85
|
+
description="Execute Python code in an isolated subprocess with stdout/stderr capture.",
|
|
86
|
+
input_schema={"code": "string", "timeout": "number?", "cwd": "string?"},
|
|
87
|
+
output_schema={"output": "string", "exit_code": "integer"},
|
|
88
|
+
permissions=["execute_python"],
|
|
89
|
+
documentation="Executes arbitrary Python code using the active Python interpreter.",
|
|
90
|
+
),
|
|
91
|
+
handler=_python_execute_handler,
|
|
92
|
+
health_checker=_check_python_health,
|
|
93
|
+
))
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Quantum SDK Capabilities Adapter per §90:
|
|
3
|
+
- qiskit.run_circuit
|
|
4
|
+
- cirq.run_circuit
|
|
5
|
+
- pennylane.run_qnode
|
|
6
|
+
- quantum.bloch_sphere (wires into existing CAT bloch logic)
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import importlib.util
|
|
12
|
+
from typing import Any, Dict, Optional, Tuple
|
|
13
|
+
|
|
14
|
+
from ..schema import (
|
|
15
|
+
AvailabilityStatus,
|
|
16
|
+
Capability,
|
|
17
|
+
CapabilityCategory,
|
|
18
|
+
CapabilitySpec,
|
|
19
|
+
ExecutionResult,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _check_qiskit_health() -> Tuple[AvailabilityStatus, str]:
|
|
24
|
+
if importlib.util.find_spec("qiskit") is not None:
|
|
25
|
+
try:
|
|
26
|
+
import qiskit
|
|
27
|
+
return AvailabilityStatus.AVAILABLE, f"Qiskit {getattr(qiskit, '__version__', 'installed')} ready"
|
|
28
|
+
except Exception as e:
|
|
29
|
+
return AvailabilityStatus.UNAVAILABLE, str(e)
|
|
30
|
+
return AvailabilityStatus.SOFTWARE_NOT_FOUND, "Qiskit is not installed (run: pip install qiskit)"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _check_cirq_health() -> Tuple[AvailabilityStatus, str]:
|
|
34
|
+
if importlib.util.find_spec("cirq") is not None:
|
|
35
|
+
try:
|
|
36
|
+
import cirq
|
|
37
|
+
return AvailabilityStatus.AVAILABLE, f"Cirq {getattr(cirq, '__version__', 'installed')} ready"
|
|
38
|
+
except Exception as e:
|
|
39
|
+
return AvailabilityStatus.UNAVAILABLE, str(e)
|
|
40
|
+
return AvailabilityStatus.SOFTWARE_NOT_FOUND, "Cirq is not installed (run: pip install cirq)"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _check_pennylane_health() -> Tuple[AvailabilityStatus, str]:
|
|
44
|
+
if importlib.util.find_spec("pennylane") is not None:
|
|
45
|
+
try:
|
|
46
|
+
import pennylane
|
|
47
|
+
return AvailabilityStatus.AVAILABLE, f"PennyLane {getattr(pennylane, '__version__', 'installed')} ready"
|
|
48
|
+
except Exception as e:
|
|
49
|
+
return AvailabilityStatus.UNAVAILABLE, str(e)
|
|
50
|
+
return AvailabilityStatus.SOFTWARE_NOT_FOUND, "PennyLane is not installed (run: pip install pennylane)"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _bloch_handler(args: Dict[str, Any], context: Optional[Dict[str, Any]] = None) -> ExecutionResult:
|
|
54
|
+
theta = float(args.get("theta", 0.0))
|
|
55
|
+
phi = float(args.get("phi", 0.0))
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
from ...derivations import bloch_state
|
|
59
|
+
res = bloch_state(theta, phi)
|
|
60
|
+
return ExecutionResult(success=True, output=res, metadata={"theta": theta, "phi": phi})
|
|
61
|
+
except Exception:
|
|
62
|
+
# Fallback math calculation of state vector
|
|
63
|
+
import math
|
|
64
|
+
theta_rad = math.radians(theta)
|
|
65
|
+
phi_rad = math.radians(phi)
|
|
66
|
+
alpha = math.cos(theta_rad / 2.0)
|
|
67
|
+
beta_real = math.sin(theta_rad / 2.0) * math.cos(phi_rad)
|
|
68
|
+
beta_imag = math.sin(theta_rad / 2.0) * math.sin(phi_rad)
|
|
69
|
+
res = {
|
|
70
|
+
"theta_deg": theta,
|
|
71
|
+
"phi_deg": phi,
|
|
72
|
+
"state_vector": f"|ψ⟩ = {alpha:.4f}|0⟩ + ({beta_real:.4f} + {beta_imag:.4f}i)|1⟩",
|
|
73
|
+
"probabilities": {"P(|0⟩)": round(alpha**2, 4), "P(|1⟩)": round(beta_real**2 + beta_imag**2, 4)},
|
|
74
|
+
}
|
|
75
|
+
return ExecutionResult(success=True, output=res, metadata={"theta": theta, "phi": phi})
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _qiskit_handler(args: Dict[str, Any], context: Optional[Dict[str, Any]] = None) -> ExecutionResult:
|
|
79
|
+
status, msg = _check_qiskit_health()
|
|
80
|
+
if status != AvailabilityStatus.AVAILABLE:
|
|
81
|
+
return ExecutionResult(success=False, error=msg, status=status)
|
|
82
|
+
|
|
83
|
+
qasm_or_code = args.get("qasm") or args.get("code", "")
|
|
84
|
+
if not qasm_or_code:
|
|
85
|
+
return ExecutionResult(success=False, error="qasm or code argument is required")
|
|
86
|
+
|
|
87
|
+
try:
|
|
88
|
+
import qiskit
|
|
89
|
+
from qiskit import QuantumCircuit
|
|
90
|
+
# If QASM string
|
|
91
|
+
if "OPENQASM" in qasm_or_code:
|
|
92
|
+
circuit = QuantumCircuit.from_qasm_str(qasm_or_code)
|
|
93
|
+
else:
|
|
94
|
+
return ExecutionResult(success=False, error="Only valid OpenQASM input is currently accepted directly")
|
|
95
|
+
|
|
96
|
+
# Run on basic simulator
|
|
97
|
+
try:
|
|
98
|
+
from qiskit_aer import Aer
|
|
99
|
+
backend = Aer.get_backend("aer_simulator")
|
|
100
|
+
except ImportError:
|
|
101
|
+
backend = qiskit.providers.basic_provider.BasicSimulator()
|
|
102
|
+
|
|
103
|
+
job = backend.run(circuit, shots=args.get("shots", 1024))
|
|
104
|
+
counts = job.result().get_counts()
|
|
105
|
+
return ExecutionResult(
|
|
106
|
+
success=True,
|
|
107
|
+
output={"counts": counts, "qubits": circuit.num_qubits, "depth": circuit.depth()},
|
|
108
|
+
metadata={"shots": args.get("shots", 1024)},
|
|
109
|
+
)
|
|
110
|
+
except Exception as e:
|
|
111
|
+
return ExecutionResult(success=False, error=f"Qiskit circuit execution error: {e}")
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def _cirq_handler(args: Dict[str, Any], context: Optional[Dict[str, Any]] = None) -> ExecutionResult:
|
|
115
|
+
status, msg = _check_cirq_health()
|
|
116
|
+
if status != AvailabilityStatus.AVAILABLE:
|
|
117
|
+
return ExecutionResult(success=False, error=msg, status=status)
|
|
118
|
+
return ExecutionResult(success=True, output="Cirq simulator ready. Provide circuit object via python capability.")
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def register_quantum_capabilities(bus):
|
|
122
|
+
bus.register(Capability(
|
|
123
|
+
spec=CapabilitySpec(
|
|
124
|
+
name="quantum.bloch_sphere",
|
|
125
|
+
version="1.0.0",
|
|
126
|
+
category=CapabilityCategory.QUANTUM,
|
|
127
|
+
description="Compute single-qubit Bloch sphere coordinates, state vector, and probabilities.",
|
|
128
|
+
input_schema={"theta": "number", "phi": "number"},
|
|
129
|
+
output_schema={"state_vector": "string", "probabilities": "object"},
|
|
130
|
+
permissions=["read_workspace"],
|
|
131
|
+
documentation="Evaluates |ψ⟩ = cos(θ/2)|0⟩ + e^(iφ)sin(θ/2)|1⟩.",
|
|
132
|
+
),
|
|
133
|
+
handler=_bloch_handler,
|
|
134
|
+
health_checker=lambda: (AvailabilityStatus.AVAILABLE, "Bloch sphere engine ready"),
|
|
135
|
+
))
|
|
136
|
+
|
|
137
|
+
bus.register(Capability(
|
|
138
|
+
spec=CapabilitySpec(
|
|
139
|
+
name="qiskit.run_circuit",
|
|
140
|
+
version="1.0.0",
|
|
141
|
+
category=CapabilityCategory.QUANTUM,
|
|
142
|
+
description="Simulate a quantum circuit using Qiskit Aer or BasicSimulator.",
|
|
143
|
+
input_schema={"qasm": "string", "shots": "integer?"},
|
|
144
|
+
output_schema={"counts": "object"},
|
|
145
|
+
permissions=["execute_python"],
|
|
146
|
+
documentation="Executes quantum circuit simulation if Qiskit is installed.",
|
|
147
|
+
),
|
|
148
|
+
handler=_qiskit_handler,
|
|
149
|
+
health_checker=_check_qiskit_health,
|
|
150
|
+
))
|