terradev-cli 6.2.1__tar.gz → 6.2.2__tar.gz
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.
- {terradev_cli-6.2.1/terradev_cli.egg-info → terradev_cli-6.2.2}/PKG-INFO +32 -6
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/README.md +30 -4
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/pyproject.toml +3 -2
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/README.md +12 -9
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/__init__.py +2 -2
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/_api.py +88 -8
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/canary.py +162 -1
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/providers.py +8 -8
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/credential_prompt.py +10 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/drift_monitor/agent.py +26 -1
- terradev_cli-6.2.2/terradev_cli/drift_monitor/ml_service_contracts/langfuse.yaml +19 -0
- terradev_cli-6.2.2/terradev_cli/drift_monitor/ml_service_contracts/letta.yaml +12 -0
- terradev_cli-6.2.2/terradev_cli/drift_monitor/ml_service_contracts/ollama.yaml +25 -0
- terradev_cli-6.2.2/terradev_cli/drift_monitor/ml_service_contracts/qdrant.yaml +27 -0
- terradev_cli-6.2.2/terradev_cli/drift_monitor/ml_service_contracts/ray.yaml +26 -0
- terradev_cli-6.2.2/terradev_cli/drift_monitor/ml_service_contracts/weaviate.yaml +26 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/handlers/compute.py +1 -1
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/schemas/compute.py +1 -1
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/schemas/core.py +2 -2
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/schemas/inference.py +1 -1
- terradev_cli-6.2.2/terradev_cli/providers/contracts/gcore.yaml +86 -0
- terradev_cli-6.2.2/terradev_cli/providers/gcore_provider.py +561 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/provider_factory.py +1 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/provider_profiles.py +18 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2/terradev_cli.egg-info}/PKG-INFO +32 -6
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli.egg-info/SOURCES.txt +12 -0
- terradev_cli-6.2.2/tests/test_agent_chaos.py +409 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_cli_smoke.py +41 -0
- terradev_cli-6.2.2/tests/test_drift_auth_and_errors.py +372 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_drift_monitor.py +121 -0
- terradev_cli-6.2.2/tests/test_ml_drift_credentials.py +38 -0
- terradev_cli-6.2.2/tests/test_ml_service_contracts.py +112 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/LICENSE +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/setup.cfg +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/__main__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/cli.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/cli_hf_spaces.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/cli_karpenter.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/__init__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/agent_infra/__init__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/agent_infra/core.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/agent_infra/dependency_manager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/agent_infra/landlock.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/agent_infra/mcp.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/agent_infra/mesh.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/agent_infra/otel.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/agent_infra/sandbox.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/compute.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/database.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/gateway.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/inference.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/infrastructure.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/k8s.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/letta.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/login.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/ml.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/mlops.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/platform.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/sso.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/telinea.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/training.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/unsloth.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/vault.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/commands/weaviate.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/__init__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/adapters/__init__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/adapters/base.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/adapters/builtins/__init__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/adapters/builtins/compute.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/adapters/builtins/database.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/adapters/builtins/datasets.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/adapters/builtins/models.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/adapters/builtins/serving.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/adapters/capabilities.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/adapters/exceptions.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/adapters/orchestrator.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/adapters/registry.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/agentic_provisioner.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/agentic_topology.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/async_config.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/auth.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/auto_lineage.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/cache_manager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/checkpoint_manager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/command_executor.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/config.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/config_validator.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/cost_scaler.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/cost_tracker.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/credential_vault.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/cuda_graph_integrator.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/dag_executor.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/data_governance.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/database_connection.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/dataset_stager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/deployment_router.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/distributed_lock.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/drift_detector.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/egress_cost_monitor.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/egress_optimizer.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/enterprise_auth.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/evaluation_orchestrator.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/event_system.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/gateway_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/gitops_manager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/gpu_discovery.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/gpu_topology.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/helm_generator.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/hf_cli_integration.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/hf_smart_templates.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/hf_spaces.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/inference_router.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/inference_spot_manager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/job_state_manager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/kv_cache_checkpoint_manager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/kv_cache_checkpoint_tests.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/kv_sharing.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/lora_consistency.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/lora_cost_attribution.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/lora_versioning.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/manifest_cache.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/mig_manager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/migration_orchestrator.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/mla_vram_estimator.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/mla_vram_tests.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/model_orchestrator.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/monitoring.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/node_span_stream.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/observe.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/oidc_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/optimization_config.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/output.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/parallel_provisioner.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/pd_transport.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/pipeline_schema.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/preflight_validator.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/price_discovery.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/price_intelligence.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/provision_preflight.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/public_ip_billing_tracker.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/quick_start.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/quota_manager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/rate_limiter.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/redis_span_exporter.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/result.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/rust_telemetry.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/saml_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/schedule.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/semantic_router.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/semantic_signals/__init__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/semantic_signals/base_signal.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/semantic_signals/complexity_signal.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/semantic_signals/domain_signal.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/semantic_signals/keyword_signal.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/semantic_signals/language_signal.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/semantic_signals/modality_signal.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/semantic_signals/orchestrator.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/semantic_signals/routing_policy.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/semantic_signals/safety_signal.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/session_manager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/ssh_key_manager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/telemetry.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/telinea/__init__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/telinea/auth.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/telinea/client.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/telinea/config.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/telinea/connector.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/telinea/payload.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/terradev_engine.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/trace_viewer.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/training_monitor.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/training_orchestrator.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/training_pipeline.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/training_stages.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/universal_manifest.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/user_manager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/vault_adapter.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/warm_pool_manager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/weight_streaming_benchmarks.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/core/weight_streaming_manager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/cost_optimizer.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/demo.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/drift_monitor/__init__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/entry_point.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/integrations/Terradev LOGO BLACK.png +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/integrations/Terradev LOGO WHITEW.png +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/integrations/__init__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/integrations/datadog_integration.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/integrations/wandb_integration.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/k8s/terraform_wrapper.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/kubernetes/inferx-infrastructure.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/kubernetes/inferx-platform.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/__init__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/executor.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/handlers/__init__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/handlers/agentic.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/handlers/core.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/handlers/gitops.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/handlers/governance.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/handlers/inference.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/handlers/integrations.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/handlers/k8s.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/handlers/ml.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/handlers/monitoring.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/handlers/networking.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/handlers/orchestration.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/handlers/pricing.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/handlers/training.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/handlers/unsloth.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/handlers/vllm_lora.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/handlers/weaviate.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/new_feature_tools.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/registry_data.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/router.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/schemas/__init__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/schemas/agentic.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/schemas/gitops.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/schemas/governance.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/schemas/integrations.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/schemas/k8s.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/schemas/ml.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/schemas/monitoring.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/schemas/networking.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/schemas/orchestration.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/schemas/pricing.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/schemas/training.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/schemas/unsloth.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/schemas/vllm_lora.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/schemas/weaviate.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/mcp/server.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/__init__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/agentic_serving.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/drift_retrain_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/dvc_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/guardrails_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/huggingface_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/kserve_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/kubernetes_enhanced.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/kubernetes_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/langchain_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/langfuse_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/langgraph_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/lmcache_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/lora_registry.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/lorax_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/mlflow_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/model_router.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/ollama_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/peft_import_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/phoenix_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/qdrant_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/ray_enhanced.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/ray_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/sglang_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/vllm_service.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/ml_services/wandb_enhanced.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/optimization/__init__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/optimization/auto_optimizer.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/optimization/cuco_optimizer.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/__init__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/alibaba_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/aws_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/azure_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/base_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/baseten_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/contracts/__init__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/contracts/aws.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/contracts/azure.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/contracts/baseten.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/contracts/crusoe.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/contracts/digitalocean.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/contracts/e2enetworks.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/contracts/gcp.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/contracts/huggingface.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/contracts/hyperstack.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/contracts/inferx.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/contracts/latitude.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/contracts/ovhcloud.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/contracts/runpod.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/contracts/siliconflow.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/contracts/tensordock.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/contracts/vastai.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/contracts/yottalabs.yaml +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/crusoe_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/demo_mode.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/digitalocean_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/e2e_networks_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/gcp_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/gpu_catalog.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/huggingface_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/hyperstack_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/inferx_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/latitude_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/oracle_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/ovhcloud_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/real_pricing.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/registry.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/runpod_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/siliconflow_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/tensordock_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/types.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/vastai_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/providers/yottalabs_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/main.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/__init__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-aws/bootstrap.sh +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-aws/main.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-aws/outputs.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-aws/variables.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-aws/versions.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-hyperstack/bootstrap.sh +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-hyperstack/main.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-hyperstack/outputs.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-hyperstack/variables.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-hyperstack/versions.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-lambda/bootstrap.sh +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-lambda/main.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-lambda/outputs.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-lambda/variables.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-lambda/versions.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-vastai/bootstrap.sh +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-vastai/main.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-vastai/outputs.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-vastai/variables.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/gpu-node-vastai/versions.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/k8s-control-plane/join-script.tpl +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/k8s-control-plane/kubeconfig.tpl +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/k8s-control-plane/main.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/k8s-control-plane/outputs.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/k8s-control-plane/variables.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/k8s-control-plane/versions.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/networking/main.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/networking/outputs.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/networking/variables.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/modules/networking/versions.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/outputs.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/price-optimizer/optimal-allocation.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/providers.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/terraform/variables.tf +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/test_summary.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/utils/__init__.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli/utils/formatters.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli.egg-info/dependency_links.txt +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli.egg-info/entry_points.txt +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli.egg-info/requires.txt +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/terradev_cli.egg-info/top_level.txt +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_ai_integrations.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_aiohttp_chaos.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_base_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_canary_provisioning.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_checkpoint_manager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_cli_commands.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_cli_utils.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_commands_functional_missing.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_commands_help.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_commands_help_full.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_core_components.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_core_smoke.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_cost_optimizer.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_cuco_optimizer.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_datadog_integration.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_deep_property_based.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_deep_quote_fault_injection.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_deep_state_invariants.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_demo_mode.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_drift_contracts.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_flashoptim.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_formatters.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_generated_artifacts.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_gpu_catalog.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_hf_smart_templates.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_integration.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_k8s_regression.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_latitude_provider.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_low_coverage_canary.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_low_coverage_hypothesis.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_major_providers.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_mcp_all_tools.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_mcp_call_tool_compat.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_mcp_chaos.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_mcp_contract.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_mcp_handlers.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_mcp_server.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_mcp_snapshots.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_ml_integrations.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_module_imports.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_new_providers.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_preflight_dataclasses.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_provider_api_contracts.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_provider_concurrency.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_provider_conformance.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_provider_profiles.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_provider_smoke.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_providers.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_quote_properties.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_real_pricing.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_root_dag_executor.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_root_job_state_manager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_root_provider_factory.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_root_semantic_router.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_root_session_manager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_root_ssh_key_manager.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_root_trace_viewer.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_sglang_optimization.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_terradev_engine.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_tpu.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_training_monitor.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_training_orchestrator.py +0 -0
- {terradev_cli-6.2.1 → terradev_cli-6.2.2}/tests/test_vllm_features.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: terradev-cli
|
|
3
|
-
Version: 6.2.
|
|
4
|
-
Summary: Imperative Command Line Interface for AI Workload Orchestration.
|
|
3
|
+
Version: 6.2.2
|
|
4
|
+
Summary: Imperative Command Line Interface for AI Workload Orchestration across 18 GPU cloud providers.
|
|
5
5
|
Author-email: Terradev Team <team@terradev.com>
|
|
6
6
|
Maintainer-email: Terradev Team <team@terradev.com>
|
|
7
7
|
License: Apache-2.0
|
|
@@ -107,9 +107,9 @@ Requires-Dist: redis>=5.0.0; extra == "enterprise"
|
|
|
107
107
|
Requires-Dist: PyJWT>=2.8.0; extra == "enterprise"
|
|
108
108
|
Dynamic: license-file
|
|
109
109
|
|
|
110
|
-
# Terradev-cli 6.2.
|
|
110
|
+
# Terradev-cli 6.2.2
|
|
111
111
|
|
|
112
|
-
**Imperative Command Line Interface for AI Workload Orchestration.**
|
|
112
|
+
**Imperative Command Line Interface for AI Workload Orchestration across 18 GPU cloud providers.**
|
|
113
113
|
|
|
114
114
|

|
|
115
115
|
|
|
@@ -126,6 +126,32 @@ Continued focus on lower cost, faster provisioning, and topology-aware execution
|
|
|
126
126
|
|
|
127
127
|
Model agnostic. Dataset agnostic. GPU agnostic. Provider agnostic. The only thing Terradev is not agnostic about is correctness: it enforces topology, idempotency, and sequencing.
|
|
128
128
|
|
|
129
|
+
**NOTES ON v6.2.2**
|
|
130
|
+
|
|
131
|
+
- Version bumped to **v6.2.2**.
|
|
132
|
+
- Provider list consolidated to **18 active GPU cloud and inference providers**:
|
|
133
|
+
- `aws` — Amazon Web Services
|
|
134
|
+
- `azure` — Microsoft Azure
|
|
135
|
+
- `baseten` — Baseten
|
|
136
|
+
- `crusoe` — Crusoe Cloud
|
|
137
|
+
- `digitalocean` — DigitalOcean
|
|
138
|
+
- `e2enetworks` — E2E Networks
|
|
139
|
+
- `gcore` — Gcore
|
|
140
|
+
- `gcp` — Google Cloud Platform
|
|
141
|
+
- `huggingface` — Hugging Face
|
|
142
|
+
- `hyperstack` — Hyperstack
|
|
143
|
+
- `inferx` — InferX
|
|
144
|
+
- `latitude` — Latitude.sh
|
|
145
|
+
- `ovhcloud` — OVHcloud
|
|
146
|
+
- `runpod` — RunPod
|
|
147
|
+
- `siliconflow` — SiliconFlow
|
|
148
|
+
- `tensordock` — TensorDock
|
|
149
|
+
- `vastai` — Vast.ai
|
|
150
|
+
- `yottalabs` — YottaLabs
|
|
151
|
+
- Added Gcore (`gcore`) as a new VM provider with full lifecycle support, API token auth, and drift monitoring.
|
|
152
|
+
- Removed Jio Cloud and Oracle Cloud from the active provider list; removed Alibaba Cloud references from the CLI UI.
|
|
153
|
+
- Onboarding, `configure`, `setup`, `quote`, `credential_prompt`, and MCP tool schemas now all reflect the 18-provider set.
|
|
154
|
+
|
|
129
155
|
**NOTES ON Multi-Stage Training Pipeline (v6.1.1)**
|
|
130
156
|
|
|
131
157
|
- New `terradev train` subcommands for the full post-pretraining lifecycle:
|
|
@@ -333,7 +359,7 @@ terradev --help
|
|
|
333
359
|
```
|
|
334
360
|
|
|
335
361
|
### Step 2: Configure Your First Cloud Provider
|
|
336
|
-
Terradev supports
|
|
362
|
+
Terradev supports 18 GPU cloud providers. Start with one, RunPod is the fastest to set up:
|
|
337
363
|
|
|
338
364
|
```bash
|
|
339
365
|
terradev setup runpod --quick
|
|
@@ -564,7 +590,7 @@ Terradev handles the foundation automatically so the rest of the stack works the
|
|
|
564
590
|
# Set up cloud provider credentials
|
|
565
591
|
terradev configure
|
|
566
592
|
|
|
567
|
-
# Real-time GPU pricing across
|
|
593
|
+
# Real-time GPU pricing across 18 clouds
|
|
568
594
|
terradev quote -g H100
|
|
569
595
|
|
|
570
596
|
# Provision with auto topology optimization
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Terradev-cli 6.2.
|
|
1
|
+
# Terradev-cli 6.2.2
|
|
2
2
|
|
|
3
|
-
**Imperative Command Line Interface for AI Workload Orchestration.**
|
|
3
|
+
**Imperative Command Line Interface for AI Workload Orchestration across 18 GPU cloud providers.**
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
|
|
@@ -17,6 +17,32 @@ Continued focus on lower cost, faster provisioning, and topology-aware execution
|
|
|
17
17
|
|
|
18
18
|
Model agnostic. Dataset agnostic. GPU agnostic. Provider agnostic. The only thing Terradev is not agnostic about is correctness: it enforces topology, idempotency, and sequencing.
|
|
19
19
|
|
|
20
|
+
**NOTES ON v6.2.2**
|
|
21
|
+
|
|
22
|
+
- Version bumped to **v6.2.2**.
|
|
23
|
+
- Provider list consolidated to **18 active GPU cloud and inference providers**:
|
|
24
|
+
- `aws` — Amazon Web Services
|
|
25
|
+
- `azure` — Microsoft Azure
|
|
26
|
+
- `baseten` — Baseten
|
|
27
|
+
- `crusoe` — Crusoe Cloud
|
|
28
|
+
- `digitalocean` — DigitalOcean
|
|
29
|
+
- `e2enetworks` — E2E Networks
|
|
30
|
+
- `gcore` — Gcore
|
|
31
|
+
- `gcp` — Google Cloud Platform
|
|
32
|
+
- `huggingface` — Hugging Face
|
|
33
|
+
- `hyperstack` — Hyperstack
|
|
34
|
+
- `inferx` — InferX
|
|
35
|
+
- `latitude` — Latitude.sh
|
|
36
|
+
- `ovhcloud` — OVHcloud
|
|
37
|
+
- `runpod` — RunPod
|
|
38
|
+
- `siliconflow` — SiliconFlow
|
|
39
|
+
- `tensordock` — TensorDock
|
|
40
|
+
- `vastai` — Vast.ai
|
|
41
|
+
- `yottalabs` — YottaLabs
|
|
42
|
+
- Added Gcore (`gcore`) as a new VM provider with full lifecycle support, API token auth, and drift monitoring.
|
|
43
|
+
- Removed Jio Cloud and Oracle Cloud from the active provider list; removed Alibaba Cloud references from the CLI UI.
|
|
44
|
+
- Onboarding, `configure`, `setup`, `quote`, `credential_prompt`, and MCP tool schemas now all reflect the 18-provider set.
|
|
45
|
+
|
|
20
46
|
**NOTES ON Multi-Stage Training Pipeline (v6.1.1)**
|
|
21
47
|
|
|
22
48
|
- New `terradev train` subcommands for the full post-pretraining lifecycle:
|
|
@@ -224,7 +250,7 @@ terradev --help
|
|
|
224
250
|
```
|
|
225
251
|
|
|
226
252
|
### Step 2: Configure Your First Cloud Provider
|
|
227
|
-
Terradev supports
|
|
253
|
+
Terradev supports 18 GPU cloud providers. Start with one, RunPod is the fastest to set up:
|
|
228
254
|
|
|
229
255
|
```bash
|
|
230
256
|
terradev setup runpod --quick
|
|
@@ -455,7 +481,7 @@ Terradev handles the foundation automatically so the rest of the stack works the
|
|
|
455
481
|
# Set up cloud provider credentials
|
|
456
482
|
terradev configure
|
|
457
483
|
|
|
458
|
-
# Real-time GPU pricing across
|
|
484
|
+
# Real-time GPU pricing across 18 clouds
|
|
459
485
|
terradev quote -g H100
|
|
460
486
|
|
|
461
487
|
# Provision with auto topology optimization
|
|
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "terradev-cli"
|
|
7
|
-
version = "6.2.
|
|
8
|
-
description = "Imperative Command Line Interface for AI Workload Orchestration."
|
|
7
|
+
version = "6.2.2"
|
|
8
|
+
description = "Imperative Command Line Interface for AI Workload Orchestration across 18 GPU cloud providers."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "Apache-2.0"}
|
|
11
11
|
authors = [
|
|
@@ -231,6 +231,7 @@ source = ["terradev_cli"]
|
|
|
231
231
|
terradev_cli = [
|
|
232
232
|
"README.md",
|
|
233
233
|
"core/semantic_signals/*.yaml",
|
|
234
|
+
"drift_monitor/ml_service_contracts/*.yaml",
|
|
234
235
|
"integrations/*.png",
|
|
235
236
|
"kubernetes/*.yaml",
|
|
236
237
|
"providers/contracts/*.yaml",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# Terradev-cli 6.2.
|
|
1
|
+
# Terradev-cli 6.2.2
|
|
2
2
|
|
|
3
3
|
## An imperative Command Line Interface for AI Workload Orchestration
|
|
4
4
|
|
|
5
|
-
**Imperative Command Line Interface for AI Workload Orchestration.**
|
|
5
|
+
**Imperative Command Line Interface for AI Workload Orchestration across 18 GPU cloud providers.**
|
|
6
6
|
|
|
7
7
|

|
|
8
8
|
|
|
@@ -18,21 +18,21 @@ Continued focus on lower cost, faster provisioning, and topology-aware execution
|
|
|
18
18
|
|
|
19
19
|
Model agnostic. Dataset agnostic. GPU agnostic. Provider agnostic. The only thing Terradev is not agnostic about is correctness: it enforces topology, idempotency, and sequencing.
|
|
20
20
|
|
|
21
|
-
**NOTES ON v6.2.
|
|
21
|
+
**NOTES ON v6.2.2**
|
|
22
22
|
|
|
23
|
-
- Version bumped to **v6.2.
|
|
24
|
-
- Provider list
|
|
25
|
-
- The following 17 providers are available for quoting and provisioning:
|
|
23
|
+
- Version bumped to **v6.2.2**.
|
|
24
|
+
- Provider list consolidated to **18 active GPU cloud and inference providers**:
|
|
26
25
|
- `aws` — Amazon Web Services
|
|
27
26
|
- `azure` — Microsoft Azure
|
|
28
27
|
- `baseten` — Baseten
|
|
29
28
|
- `crusoe` — Crusoe Cloud
|
|
30
29
|
- `digitalocean` — DigitalOcean
|
|
31
30
|
- `e2enetworks` — E2E Networks
|
|
31
|
+
- `gcore` — Gcore
|
|
32
32
|
- `gcp` — Google Cloud Platform
|
|
33
33
|
- `huggingface` — Hugging Face
|
|
34
34
|
- `hyperstack` — Hyperstack
|
|
35
|
-
- `inferx` —
|
|
35
|
+
- `inferx` — InferX
|
|
36
36
|
- `latitude` — Latitude.sh
|
|
37
37
|
- `ovhcloud` — OVHcloud
|
|
38
38
|
- `runpod` — RunPod
|
|
@@ -40,6 +40,9 @@ Model agnostic. Dataset agnostic. GPU agnostic. Provider agnostic. The only thin
|
|
|
40
40
|
- `tensordock` — TensorDock
|
|
41
41
|
- `vastai` — Vast.ai
|
|
42
42
|
- `yottalabs` — YottaLabs
|
|
43
|
+
- Added Gcore (`gcore`) as a new VM provider with full lifecycle support, API token auth, and drift monitoring.
|
|
44
|
+
- Removed Jio Cloud and Oracle Cloud from the active provider list; removed Alibaba Cloud references from the CLI UI.
|
|
45
|
+
- Onboarding, `configure`, `setup`, `quote`, `credential_prompt`, and MCP tool schemas now all reflect the 18-provider set.
|
|
43
46
|
|
|
44
47
|
**NOTES ON Multi-Stage Training Pipeline (v6.1.1)**
|
|
45
48
|
|
|
@@ -191,7 +194,7 @@ terradev --help
|
|
|
191
194
|
```
|
|
192
195
|
|
|
193
196
|
### Step 2: Configure Your First Cloud Provider
|
|
194
|
-
Terradev supports
|
|
197
|
+
Terradev supports 18 GPU cloud providers. Start with one, RunPod is the fastest to set up:
|
|
195
198
|
|
|
196
199
|
```bash
|
|
197
200
|
terradev setup runpod --quick
|
|
@@ -421,7 +424,7 @@ Terradev handles the foundation automatically so the rest of the stack works the
|
|
|
421
424
|
# Set up cloud provider credentials
|
|
422
425
|
terradev configure
|
|
423
426
|
|
|
424
|
-
# Real-time GPU pricing across
|
|
427
|
+
# Real-time GPU pricing across 18 clouds
|
|
425
428
|
terradev quote -g H100
|
|
426
429
|
|
|
427
430
|
# Provision with auto topology optimization
|
|
@@ -8,7 +8,7 @@ try:
|
|
|
8
8
|
|
|
9
9
|
__version__ = version("terradev-cli")
|
|
10
10
|
except PackageNotFoundError:
|
|
11
|
-
__version__ = "6.2.
|
|
11
|
+
__version__ = "6.2.2"
|
|
12
12
|
|
|
13
13
|
__author__ = "Terradev Team"
|
|
14
|
-
__description__ = "Imperative Command Line Interface for AI Workload Orchestration."
|
|
14
|
+
__description__ = "Imperative Command Line Interface for AI Workload Orchestration across 18 GPU cloud providers."
|
|
@@ -438,6 +438,11 @@ class TerradevAPI:
|
|
|
438
438
|
creds["api_key"] = self.credentials.get("latitude_api_key", "")
|
|
439
439
|
elif provider_name == "yottalabs":
|
|
440
440
|
creds["api_key"] = self.credentials.get("yottalabs_api_key", "")
|
|
441
|
+
elif provider_name == "gcore":
|
|
442
|
+
creds["api_key"] = self.credentials.get("gcore_api_key", "")
|
|
443
|
+
creds["project_id"] = self.credentials.get("gcore_project_id", "")
|
|
444
|
+
creds["region_id"] = self.credentials.get("gcore_region_id", "")
|
|
445
|
+
creds["region"] = self.credentials.get("gcore_region", "")
|
|
441
446
|
# ML Services
|
|
442
447
|
elif provider_name == "kserve":
|
|
443
448
|
creds["namespace"] = self.credentials.get("kserve_namespace", "default")
|
|
@@ -639,6 +644,9 @@ class TerradevAPI:
|
|
|
639
644
|
async def get_yottalabs_quotes(self, gpu_type: str):
|
|
640
645
|
return await self._get_provider_quotes("yottalabs", gpu_type)
|
|
641
646
|
|
|
647
|
+
async def get_gcore_quotes(self, gpu_type: str):
|
|
648
|
+
return await self._get_provider_quotes("gcore", gpu_type)
|
|
649
|
+
|
|
642
650
|
|
|
643
651
|
def run_interactive_onboarding(api: TerradevAPI):
|
|
644
652
|
"""Interactive onboarding flow for first-time users."""
|
|
@@ -831,14 +839,6 @@ def run_interactive_onboarding(api: TerradevAPI):
|
|
|
831
839
|
"env_var": "TENSORDOCK_API_KEY",
|
|
832
840
|
"why": "Budget-friendly, good for experiments",
|
|
833
841
|
},
|
|
834
|
-
"oracle": {
|
|
835
|
-
"name": "Oracle Cloud",
|
|
836
|
-
"key_name": "API Key",
|
|
837
|
-
"help": "Uses an OCI config file: tenancy OCID, user OCID, fingerprint, private key file, region. Generate at OCI Console → Profile → API Keys.",
|
|
838
|
-
"example": "ocid1.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
839
|
-
"env_var": "OCI_API_KEY",
|
|
840
|
-
"why": "Reliable infrastructure, competitive pricing",
|
|
841
|
-
},
|
|
842
842
|
"crusoe": {
|
|
843
843
|
"name": "Crusoe Cloud",
|
|
844
844
|
"key_name": "Access Key",
|
|
@@ -847,6 +847,62 @@ def run_interactive_onboarding(api: TerradevAPI):
|
|
|
847
847
|
"env_var": "CRUSOE_ACCESS_KEY",
|
|
848
848
|
"why": "Sustainable computing, unique GPU options",
|
|
849
849
|
},
|
|
850
|
+
"huggingface": {
|
|
851
|
+
"name": "HuggingFace",
|
|
852
|
+
"key_name": "API Token",
|
|
853
|
+
"help": "Get from: https://huggingface.co/settings/tokens",
|
|
854
|
+
"example": "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
855
|
+
"env_var": "HUGGINGFACE_API_TOKEN",
|
|
856
|
+
"why": "Serverless inference and dedicated GPU endpoints",
|
|
857
|
+
},
|
|
858
|
+
"baseten": {
|
|
859
|
+
"name": "Baseten",
|
|
860
|
+
"key_name": "API Key",
|
|
861
|
+
"help": "Get from: Baseten dashboard",
|
|
862
|
+
"example": "bt_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
863
|
+
"env_var": "BASETEN_API_KEY",
|
|
864
|
+
"why": "Model deployment platform with GPU serving",
|
|
865
|
+
},
|
|
866
|
+
"hyperstack": {
|
|
867
|
+
"name": "Hyperstack",
|
|
868
|
+
"key_name": "API Key",
|
|
869
|
+
"help": "Get from: Hyperstack dashboard → API Keys",
|
|
870
|
+
"example": "hs_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
871
|
+
"env_var": "HYPERSTACK_API_KEY",
|
|
872
|
+
"why": "High-performance cloud GPU instances",
|
|
873
|
+
},
|
|
874
|
+
"digitalocean": {
|
|
875
|
+
"name": "DigitalOcean",
|
|
876
|
+
"key_name": "API Token",
|
|
877
|
+
"help": "Get from: DigitalOcean → API → Tokens",
|
|
878
|
+
"example": "dop_v1_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
879
|
+
"env_var": "DIGITALOCEAN_API_TOKEN",
|
|
880
|
+
"why": "Simple cloud GPU droplets",
|
|
881
|
+
},
|
|
882
|
+
"e2enetworks": {
|
|
883
|
+
"name": "E2E Networks",
|
|
884
|
+
"key_name": "API Key",
|
|
885
|
+
"help": "Get from: https://e2enetworks.com",
|
|
886
|
+
"example": "e2e_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
887
|
+
"env_var": "E2ENETWORKS_API_KEY",
|
|
888
|
+
"why": "Indian cloud with GPU VMs",
|
|
889
|
+
},
|
|
890
|
+
"ovhcloud": {
|
|
891
|
+
"name": "OVHcloud",
|
|
892
|
+
"key_name": "Application Key",
|
|
893
|
+
"help": "Visit https://api.ovh.com/createToken, select GET/POST/PUT/DELETE on /cloud/* endpoints",
|
|
894
|
+
"example": "xxxxxxxxxxxxxxxx",
|
|
895
|
+
"env_var": "OVH_APPLICATION_KEY",
|
|
896
|
+
"why": "European cloud with GPU instances",
|
|
897
|
+
},
|
|
898
|
+
"siliconflow": {
|
|
899
|
+
"name": "SiliconFlow",
|
|
900
|
+
"key_name": "API Key",
|
|
901
|
+
"help": "Get from: https://cloud.siliconflow.cn/account/ak",
|
|
902
|
+
"example": "sf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
903
|
+
"env_var": "SILICONFLOW_API_KEY",
|
|
904
|
+
"why": "Fast inference API for LLMs",
|
|
905
|
+
},
|
|
850
906
|
"inferx": {
|
|
851
907
|
"name": "InferX",
|
|
852
908
|
"key_name": "API Key",
|
|
@@ -855,6 +911,30 @@ def run_interactive_onboarding(api: TerradevAPI):
|
|
|
855
911
|
"env_var": "INFERX_API_KEY",
|
|
856
912
|
"why": "Serverless inference with OpenAI-compatible endpoints",
|
|
857
913
|
},
|
|
914
|
+
"latitude": {
|
|
915
|
+
"name": "Latitude.sh",
|
|
916
|
+
"key_name": "API Key",
|
|
917
|
+
"help": "Get from: https://latitude.sh/account/api-keys",
|
|
918
|
+
"example": "lat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
919
|
+
"env_var": "LATITUDE_API_KEY",
|
|
920
|
+
"why": "Bare metal GPU servers",
|
|
921
|
+
},
|
|
922
|
+
"yottalabs": {
|
|
923
|
+
"name": "Yotta Labs",
|
|
924
|
+
"key_name": "API Key",
|
|
925
|
+
"help": "Get from: https://yottalabs.ai",
|
|
926
|
+
"example": "yotta_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
927
|
+
"env_var": "YOTTALABS_API_KEY",
|
|
928
|
+
"why": "GPU cloud for AI workloads",
|
|
929
|
+
},
|
|
930
|
+
"gcore": {
|
|
931
|
+
"name": "Gcore",
|
|
932
|
+
"key_name": "API Token",
|
|
933
|
+
"help": "Get from: Gcore Customer Portal → Profile → API Tokens",
|
|
934
|
+
"example": "12345_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
935
|
+
"env_var": "GCORE_API_TOKEN",
|
|
936
|
+
"why": "Global cloud with GPU instances",
|
|
937
|
+
},
|
|
858
938
|
}
|
|
859
939
|
|
|
860
940
|
configured_providers = []
|
|
@@ -280,6 +280,7 @@ _DRIFT_PROVIDER_ALIASES = {
|
|
|
280
280
|
"latitude": ["latitude"],
|
|
281
281
|
"yottalabs": ["yottalabs", "yotta"],
|
|
282
282
|
"e2enetworks": ["e2enetworks", "e2e"],
|
|
283
|
+
"gcore": ["gcore"],
|
|
283
284
|
}
|
|
284
285
|
|
|
285
286
|
# Provider-specific primary env names (full names, not alias-derived).
|
|
@@ -287,6 +288,9 @@ _DRIFT_PROVIDER_KEY_ENVS: Dict[str, List[str]] = {
|
|
|
287
288
|
"aws": ["TERRADEV_AWS_ACCESS_KEY_ID"],
|
|
288
289
|
"gcp": ["TERRADEV_GCP_CREDENTIALS"],
|
|
289
290
|
"inferx": ["TERRADEV_INFERX_API_KEY"],
|
|
291
|
+
"langfuse": ["TERRADEV_LANGFUSE_PUBLIC_KEY"],
|
|
292
|
+
"letta": ["TERRADEV_LETTA_API_KEY"],
|
|
293
|
+
"weaviate": ["TERRADEV_WEAVIATE_API_KEY"],
|
|
290
294
|
}
|
|
291
295
|
|
|
292
296
|
|
|
@@ -407,6 +411,37 @@ def _load_drift_env_extras(alias: str, api_key: str) -> Optional[Dict[str, Any]]
|
|
|
407
411
|
).strip()
|
|
408
412
|
extras["model"] = os.environ.get("TERRADEV_INFERX_MODEL") or "Qwen3.8-27B-FP8"
|
|
409
413
|
|
|
414
|
+
elif alias == "langfuse":
|
|
415
|
+
public_key = api_key.strip()
|
|
416
|
+
secret_key = (os.environ.get(f"TERRADEV_{name}_SECRET_KEY") or "").strip()
|
|
417
|
+
if public_key and secret_key:
|
|
418
|
+
extras["bearer_token"] = f"{public_key}:{secret_key}"
|
|
419
|
+
extras["public_key"] = public_key
|
|
420
|
+
extras["secret_key"] = secret_key
|
|
421
|
+
extras["api_key"] = public_key
|
|
422
|
+
|
|
423
|
+
elif alias == "letta":
|
|
424
|
+
extras["api_key"] = api_key.strip()
|
|
425
|
+
extras["bearer_token"] = api_key.strip()
|
|
426
|
+
|
|
427
|
+
elif alias == "weaviate":
|
|
428
|
+
extras["api_key"] = api_key.strip()
|
|
429
|
+
extras["bearer_token"] = api_key.strip()
|
|
430
|
+
|
|
431
|
+
elif alias == "gcore":
|
|
432
|
+
extras["api_key"] = api_key.strip()
|
|
433
|
+
# Project and region are optional; Gcore can discover them via API.
|
|
434
|
+
# Add TERRADEV_GCORE_PROJECT_ID / TERRADEV_GCORE_REGION_ID to skip discovery.
|
|
435
|
+
extras["project_id"] = (
|
|
436
|
+
os.environ.get(f"TERRADEV_{name}_PROJECT_ID") or project_id or ""
|
|
437
|
+
).strip()
|
|
438
|
+
extras["region_id"] = (
|
|
439
|
+
os.environ.get(f"TERRADEV_{name}_REGION_ID") or ""
|
|
440
|
+
).strip()
|
|
441
|
+
extras["region"] = (
|
|
442
|
+
os.environ.get(f"TERRADEV_{name}_REGION") or ""
|
|
443
|
+
).strip()
|
|
444
|
+
|
|
410
445
|
if project_id:
|
|
411
446
|
extras["project_id"] = project_id
|
|
412
447
|
if location:
|
|
@@ -594,7 +629,133 @@ def canary_drift(ctx, drift_all, provider, contracts_dir, drift_format, drift_ti
|
|
|
594
629
|
providers.append(contract.get("provider") or p.stem)
|
|
595
630
|
credentials = {} if no_credentials else _load_drift_credentials(providers)
|
|
596
631
|
monitor = DriftMonitor(str(contracts_path), credentials, timeout=drift_timeout)
|
|
597
|
-
monitor.
|
|
632
|
+
monitor.results = []
|
|
633
|
+
for p in contract_files:
|
|
634
|
+
monitor.results.append(monitor.check_provider(p))
|
|
635
|
+
summary = monitor.summary()
|
|
636
|
+
|
|
637
|
+
out = get_output(ctx)
|
|
638
|
+
if drift_format:
|
|
639
|
+
out.set_format(drift_format)
|
|
640
|
+
|
|
641
|
+
if out.format == "json":
|
|
642
|
+
out._closed = True # noqa: SLF001
|
|
643
|
+
sys.stdout.write(json.dumps(summary, indent=2, default=str) + "\n")
|
|
644
|
+
if summary["drifted"]:
|
|
645
|
+
ctx.exit(1)
|
|
646
|
+
return
|
|
647
|
+
|
|
648
|
+
if out.format == "jsonl":
|
|
649
|
+
out._closed = True # noqa: SLF001
|
|
650
|
+
for r in summary["providers"]:
|
|
651
|
+
sys.stdout.write(json.dumps(r, default=str) + "\n")
|
|
652
|
+
if summary["drifted"]:
|
|
653
|
+
ctx.exit(1)
|
|
654
|
+
return
|
|
655
|
+
|
|
656
|
+
_render_drift_human(summary)
|
|
657
|
+
if summary["drifted"]:
|
|
658
|
+
ctx.exit(1)
|
|
659
|
+
|
|
660
|
+
|
|
661
|
+
def _default_ml_contracts_dir() -> Path:
|
|
662
|
+
"""Return the bundled ML service contract directory."""
|
|
663
|
+
return Path(__file__).resolve().parent.parent / "drift_monitor" / "ml_service_contracts"
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
@canary.command("ml-drift")
|
|
667
|
+
@click.option(
|
|
668
|
+
"--all",
|
|
669
|
+
"ml_all",
|
|
670
|
+
is_flag=True,
|
|
671
|
+
help="Check all ML service contracts.",
|
|
672
|
+
)
|
|
673
|
+
@click.option(
|
|
674
|
+
"--provider",
|
|
675
|
+
"-p",
|
|
676
|
+
default=None,
|
|
677
|
+
help="Check a specific ML service contract (matches filename or provider field).",
|
|
678
|
+
)
|
|
679
|
+
@click.option(
|
|
680
|
+
"--format",
|
|
681
|
+
"drift_format",
|
|
682
|
+
type=click.Choice(["human", "json", "jsonl"]),
|
|
683
|
+
default=None,
|
|
684
|
+
help="Output format for the drift report.",
|
|
685
|
+
)
|
|
686
|
+
@click.option(
|
|
687
|
+
"--timeout",
|
|
688
|
+
"drift_timeout",
|
|
689
|
+
type=int,
|
|
690
|
+
default=30,
|
|
691
|
+
help="HTTP timeout in seconds for each drift endpoint call.",
|
|
692
|
+
)
|
|
693
|
+
@click.option(
|
|
694
|
+
"--base-url",
|
|
695
|
+
"base_url",
|
|
696
|
+
default=None,
|
|
697
|
+
help="Override the base URL for all selected ML service contracts.",
|
|
698
|
+
)
|
|
699
|
+
@click.option(
|
|
700
|
+
"--no-credentials",
|
|
701
|
+
"no_credentials",
|
|
702
|
+
is_flag=True,
|
|
703
|
+
default=False,
|
|
704
|
+
help="Run drift checks without loading any credentials (only public/no-auth endpoints).",
|
|
705
|
+
)
|
|
706
|
+
@click.pass_context
|
|
707
|
+
def canary_ml_drift(ctx, ml_all, provider, drift_format, drift_timeout, base_url, no_credentials):
|
|
708
|
+
"""Run drift checks for self-hosted ML/inference services."""
|
|
709
|
+
if not ml_all and not provider:
|
|
710
|
+
get_output(ctx).error("Specify --all or --provider <name>")
|
|
711
|
+
ctx.exit(2)
|
|
712
|
+
return
|
|
713
|
+
|
|
714
|
+
contracts_path = _default_ml_contracts_dir()
|
|
715
|
+
if not contracts_path.exists():
|
|
716
|
+
get_output(ctx).error(f"Contracts directory not found: {contracts_path}")
|
|
717
|
+
ctx.exit(2)
|
|
718
|
+
return
|
|
719
|
+
|
|
720
|
+
contract_files = sorted(contracts_path.glob("*.yaml"))
|
|
721
|
+
if provider:
|
|
722
|
+
provider_lower = provider.lower()
|
|
723
|
+
matching_files = []
|
|
724
|
+
for p in contract_files:
|
|
725
|
+
with open(p, "r", encoding="utf-8") as f:
|
|
726
|
+
contract = yaml.safe_load(f) or {}
|
|
727
|
+
contract_provider = (contract.get("provider") or p.stem).lower()
|
|
728
|
+
if (
|
|
729
|
+
p.stem.lower() == provider_lower
|
|
730
|
+
or provider_lower in p.stem.lower()
|
|
731
|
+
or contract_provider == provider_lower
|
|
732
|
+
or provider_lower in contract_provider
|
|
733
|
+
):
|
|
734
|
+
matching_files.append(p)
|
|
735
|
+
contract_files = matching_files
|
|
736
|
+
|
|
737
|
+
if not contract_files:
|
|
738
|
+
get_output(ctx).error(f"No matching ML service contracts in {contracts_path}")
|
|
739
|
+
ctx.exit(2)
|
|
740
|
+
return
|
|
741
|
+
|
|
742
|
+
providers = []
|
|
743
|
+
for p in contract_files:
|
|
744
|
+
with open(p, "r", encoding="utf-8") as f:
|
|
745
|
+
contract = yaml.safe_load(f) or {}
|
|
746
|
+
providers.append(contract.get("provider") or p.stem)
|
|
747
|
+
|
|
748
|
+
credentials = {} if no_credentials else _load_drift_credentials(providers)
|
|
749
|
+
overrides = {"*": base_url} if base_url else {}
|
|
750
|
+
monitor = DriftMonitor(
|
|
751
|
+
str(contracts_path),
|
|
752
|
+
credentials,
|
|
753
|
+
timeout=drift_timeout,
|
|
754
|
+
base_url_overrides=overrides,
|
|
755
|
+
)
|
|
756
|
+
monitor.results = []
|
|
757
|
+
for p in contract_files:
|
|
758
|
+
monitor.results.append(monitor.check_provider(p))
|
|
598
759
|
summary = monitor.summary()
|
|
599
760
|
|
|
600
761
|
out = get_output(ctx)
|
|
@@ -171,12 +171,6 @@ def configure(provider):
|
|
|
171
171
|
"help": "Visit https://api.ovh.com/createToken, select GET/POST/PUT/DELETE on /cloud/* endpoints. You will receive Application Key, Application Secret and Consumer Key.",
|
|
172
172
|
"example": "xxxxxxxxxxxxxxxx",
|
|
173
173
|
},
|
|
174
|
-
"alibaba": {
|
|
175
|
-
"name": "Alibaba Cloud",
|
|
176
|
-
"key_name": "Access Key ID",
|
|
177
|
-
"help": "Alibaba Cloud Console → top-right avatar → AccessKey Management → Create AccessKey. Pair of Access Key ID and Access Key Secret.",
|
|
178
|
-
"example": "LTAIxxxxxxxxxxxxxxxxxx",
|
|
179
|
-
},
|
|
180
174
|
"hyperstack": {
|
|
181
175
|
"name": "Hyperstack",
|
|
182
176
|
"key_name": "API Key",
|
|
@@ -213,6 +207,12 @@ def configure(provider):
|
|
|
213
207
|
"help": "Get from: https://yottalabs.ai",
|
|
214
208
|
"example": "yotta_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
215
209
|
},
|
|
210
|
+
"gcore": {
|
|
211
|
+
"name": "Gcore",
|
|
212
|
+
"key_name": "API Token",
|
|
213
|
+
"help": "Get from: Gcore Customer Portal → Profile → API Tokens",
|
|
214
|
+
"example": "12345_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
215
|
+
},
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
config = provider_configs.get(provider.lower())
|
|
@@ -744,6 +744,7 @@ def quote(gpu_type, providers, parallel, region, quick, include_local):
|
|
|
744
744
|
("ovhcloud", api.get_ovhcloud_quotes),
|
|
745
745
|
("siliconflow", api.get_siliconflow_quotes),
|
|
746
746
|
("yottalabs", api.get_yottalabs_quotes),
|
|
747
|
+
("gcore", api.get_gcore_quotes),
|
|
747
748
|
]
|
|
748
749
|
for pname, fn in provider_list:
|
|
749
750
|
if not providers or pname in providers:
|
|
@@ -843,17 +844,16 @@ def quote(gpu_type, providers, parallel, region, quick, include_local):
|
|
|
843
844
|
"tensordock",
|
|
844
845
|
"crusoe",
|
|
845
846
|
"baseten",
|
|
846
|
-
"oracle",
|
|
847
847
|
"huggingface",
|
|
848
848
|
"siliconflow",
|
|
849
849
|
"ovhcloud",
|
|
850
|
-
"alibaba",
|
|
851
850
|
"hyperstack",
|
|
852
851
|
"digitalocean",
|
|
853
852
|
"inferx",
|
|
854
853
|
"e2enetworks",
|
|
855
854
|
"latitude",
|
|
856
855
|
"yottalabs",
|
|
856
|
+
"gcore",
|
|
857
857
|
]
|
|
858
858
|
),
|
|
859
859
|
)
|
|
@@ -187,6 +187,16 @@ def prompt_for_credentials():
|
|
|
187
187
|
{"key": "api_key", "label": "API Key", "hide_input": True},
|
|
188
188
|
],
|
|
189
189
|
},
|
|
190
|
+
"gcore": {
|
|
191
|
+
"name": "Gcore",
|
|
192
|
+
"help": "Get from: Gcore Customer Portal → Profile → API Tokens",
|
|
193
|
+
"example": "12345_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
194
|
+
"fields": [
|
|
195
|
+
{"key": "api_key", "label": "API Token", "hide_input": True},
|
|
196
|
+
{"key": "project_id", "label": "Project ID (optional)", "hide_input": False, "default": ""},
|
|
197
|
+
{"key": "region_id", "label": "Region ID (optional)", "hide_input": False, "default": ""},
|
|
198
|
+
],
|
|
199
|
+
},
|
|
190
200
|
}
|
|
191
201
|
|
|
192
202
|
updated_creds = existing_creds.copy()
|
|
@@ -116,10 +116,12 @@ class DriftMonitor:
|
|
|
116
116
|
contracts_dir: str,
|
|
117
117
|
credentials: Dict[str, Union[str, Dict[str, Any]]],
|
|
118
118
|
timeout: int = 30,
|
|
119
|
+
base_url_overrides: Optional[Dict[str, str]] = None,
|
|
119
120
|
):
|
|
120
121
|
self.contracts_dir = Path(contracts_dir)
|
|
121
122
|
self.credentials = credentials
|
|
122
123
|
self.timeout = timeout
|
|
124
|
+
self.base_url_overrides = base_url_overrides or {}
|
|
123
125
|
self.results: List[Dict[str, Any]] = []
|
|
124
126
|
|
|
125
127
|
def run_all(self) -> List[Dict[str, Any]]:
|
|
@@ -138,6 +140,11 @@ class DriftMonitor:
|
|
|
138
140
|
contract = yaml.safe_load(f)
|
|
139
141
|
|
|
140
142
|
provider = contract.get("provider") or contract_path.stem
|
|
143
|
+
override = self.base_url_overrides.get(provider)
|
|
144
|
+
if override:
|
|
145
|
+
contract["base_url"] = override
|
|
146
|
+
if self.base_url_overrides.get("*"):
|
|
147
|
+
contract["base_url"] = self.base_url_overrides["*"]
|
|
141
148
|
result: Dict[str, Any] = {
|
|
142
149
|
"provider": provider,
|
|
143
150
|
"checked_at": datetime.now(timezone.utc).isoformat(),
|
|
@@ -297,6 +304,21 @@ class DriftMonitor:
|
|
|
297
304
|
return result
|
|
298
305
|
|
|
299
306
|
if response.ok:
|
|
307
|
+
# Handle explicit plain-text contracts (e.g. health/readiness probes).
|
|
308
|
+
content_type = endpoint.get("content_type") or contract.get("content_type")
|
|
309
|
+
if content_type and content_type.lower() == "text/plain":
|
|
310
|
+
actual = response.text.strip()
|
|
311
|
+
expected_text = endpoint.get("expected_text", "")
|
|
312
|
+
result["raw_response_keys"] = [actual]
|
|
313
|
+
if actual != expected_text:
|
|
314
|
+
result["drift"] = True
|
|
315
|
+
result["drift_reasons"].append(
|
|
316
|
+
f"expected text {expected_text!r}, got {actual!r}"
|
|
317
|
+
)
|
|
318
|
+
if result["drift"]:
|
|
319
|
+
result["drift_summary"] = "; ".join(result["drift_reasons"])
|
|
320
|
+
return result
|
|
321
|
+
|
|
300
322
|
try:
|
|
301
323
|
body = response.json()
|
|
302
324
|
except json.JSONDecodeError:
|
|
@@ -692,7 +714,10 @@ class DriftMonitor:
|
|
|
692
714
|
if auth_type:
|
|
693
715
|
auth_lower = auth_type.lower()
|
|
694
716
|
if auth_lower == "basic":
|
|
695
|
-
|
|
717
|
+
if ":" in bearer_token:
|
|
718
|
+
token = base64.b64encode(bearer_token.encode()).decode()
|
|
719
|
+
else:
|
|
720
|
+
token = base64.b64encode(f"{bearer_token}:".encode()).decode()
|
|
696
721
|
headers[auth_header] = f"Basic {token}"
|
|
697
722
|
elif auth_lower == "bearer" and creds.get("gcp_credentials"):
|
|
698
723
|
gcp_token = self._gcp_access_token(creds)
|